public static List <Storm> CreateForecast(DateTime date, BoundingBox bounds, WorldManager world, int days) { List <Storm> foreCast = new List <Storm>(); for (int i = 0; i < days; i++) { // Each day, a storm could originate from a randomly selected biome Vector3 randomSample = MathFunctions.RandVector3Box(bounds); float rain = ChunkGenerator.GetValueAt(randomSample, Overworld.ScalarFieldType.Rainfall); float temperature = ChunkGenerator.GetValueAt(randomSample, Overworld.ScalarFieldType.Temperature); // Generate storms according to the rainfall in the biome. Up to 4 storms per day. int numStorms = (int)MathFunctions.Rand(0, rain * 4); // Space out the storms by a few hours int stormHour = MathFunctions.RandInt(0, 6); for (int j = 0; j < numStorms; j++) { bool isSnow = MathFunctions.RandEvent(1.0f - temperature); Storm storm = new Storm(world.ParticleManager, world) { WindSpeed = MathFunctions.RandVector3Cube() * 5, Intensity = MathFunctions.Rand(rain, rain * 2), Date = date + new TimeSpan(i, stormHour, 0, 0), TypeofStorm = isSnow ? StormType.SnowStorm : StormType.RainStorm }; storm.WindSpeed = new Vector3(storm.WindSpeed.X, 0, storm.WindSpeed.Z); stormHour += MathFunctions.RandInt(1, 12); foreCast.Add(storm); } } return(foreCast); }
public static Storm CreateStorm(Vector3 windSpeed, float intensity, WorldManager world) { windSpeed.Y = 0; Storm storm = new Storm(world.ParticleManager, world) { WindSpeed = windSpeed, Intensity = intensity, }; storm.Start(); return(storm); }
public static Storm CreateStorm(Vector3 windSpeed, float intensity) { windSpeed.Y = 0; Storm storm = new Storm() { WindSpeed = windSpeed, Intensity = intensity, }; storm.Start(); return(storm); }
new public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { Storm.InitializeStatics(chunks.World.ParticleManager); BoundingBox box = chunks.Bounds; box.Expand(10.0f); if (GlobalTransform.Translation.X < box.Min.X || GlobalTransform.Translation.X > box.Max.X || GlobalTransform.Translation.Z < box.Min.Z || GlobalTransform.Translation.Z > box.Max.Z) { Die(); } bool generateRainDrop = MathFunctions.RandEvent(Raininess); if (generateRainDrop) { for (int i = 0; i < MaxRainDrops; i++) { if (!RainDrops[i].IsAlive) { RainDrops[i].IsAlive = true; RainDrops[i].Pos = MathFunctions.RandVector3Box(BoundingBox); RainDrops[i].Pos = new Vector3(RainDrops[i].Pos.X, BoundingBox.Min.Y - 1, RainDrops[i].Pos.Z); RainDrops[i].Vel = Vector3.Down * Storm.Properties[TypeofStorm].RainSpeed + Velocity; break; } } } Voxel test = new Voxel(); Storm.StormProperties stormProperties = Storm.Properties[TypeofStorm]; for (int i = 0; i < MaxRainDrops; i++) { if (!RainDrops[i].IsAlive) { continue; } RainDrops[i].Pos += RainDrops[i].Vel * DwarfTime.Dt; if (stormProperties.RainRandom > 0) { RainDrops[i].Vel.X += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt; RainDrops[i].Vel.Z += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt; } if (RainDrops[i].Pos.Y < 0) { RainDrops[i].IsAlive = false; } if (!RainDrops[i].IsAlive && RainDrops[i].Particle != null) { RainDrops[i].Particle.LifeRemaining = -1; RainDrops[i].Particle = null; } else if (RainDrops[i].IsAlive && RainDrops[i].Particle == null) { RainDrops[i].Particle = stormProperties.RainEffect.Emitters[0].CreateParticle(RainDrops[i].Pos, RainDrops[i].Vel, Color.White); } else if (RainDrops[i].IsAlive && RainDrops[i].Particle != null) { RainDrops[i].Particle.Position = RainDrops[i].Pos; RainDrops[i].Particle.Velocity = RainDrops[i].Vel; } if (!chunks.ChunkData.GetVoxel(RainDrops[i].Pos, ref test)) { continue; } if (test == null || test.IsEmpty || test.WaterLevel > 0) { continue; } RainDrops[i].IsAlive = false; stormProperties.HitEffect.Trigger(1, RainDrops[i].Pos + Vector3.UnitY * 0.5f, Color.White); if (!MathFunctions.RandEvent(0.1f)) { continue; } Voxel above = test.IsEmpty ? test : test.GetVoxelAbove(); if (above == null) { continue; } if (stormProperties.CreatesLiquid && (above.WaterLevel < WaterManager.maxWaterLevel && (above.Water.Type == LiquidType.Water || above.Water.Type == LiquidType.None))) { WaterCell water = above.Water; water.WaterLevel = (byte)Math.Min(WaterManager.maxWaterLevel, water.WaterLevel + WaterManager.rainFallAmount); water.Type = stormProperties.LiquidToCreate; above.Water = water; above.Chunk.ShouldRebuildWater = true; } else if (stormProperties.CreatesVoxel && above.IsEmpty && above.WaterLevel == 0) { above.Type = stormProperties.VoxelToCreate; above.Water = new WaterCell(); above.Health = above.Type.StartingHealth; above.Chunk.NotifyTotalRebuild(!above.IsInterior); } } Matrix tf = LocalTransform; tf.Translation += Velocity * DwarfTime.Dt; LocalTransform = tf; base.Update(gameTime, chunks, camera); }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { base.Update(gameTime, chunks, camera); Storm.InitializeStatics(); BoundingBox box = chunks.Bounds; box.Expand(10.0f); if (GlobalTransform.Translation.X < box.Min.X || GlobalTransform.Translation.X > box.Max.X || GlobalTransform.Translation.Z < box.Min.Z || GlobalTransform.Translation.Z > box.Max.Z) { Die(); } bool generateRainDrop = MathFunctions.RandEvent(Raininess * 0.75f); if (generateRainDrop) { for (int i = 0; i < MaxRainDrops; i++) { if (!RainDrops[i].IsAlive) { RainDrops[i].IsAlive = true; RainDrops[i].Pos = MathFunctions.RandVector3Box(BoundingBox.Expand(5)); RainDrops[i].Pos = new Vector3(RainDrops[i].Pos.X, BoundingBox.Min.Y - 1, RainDrops[i].Pos.Z); RainDrops[i].Vel = Vector3.Down * Storm.Properties[TypeofStorm].RainSpeed + Velocity; break; } } } Storm.StormProperties stormProperties = Storm.Properties[TypeofStorm]; var rainEmitter = World.ParticleManager.Effects[stormProperties.RainEffect]; var hitEmitter = World.ParticleManager.Effects[stormProperties.HitEffect]; for (int i = 0; i < MaxRainDrops; i++) { if (!RainDrops[i].IsAlive) { continue; } RainDrops[i].Pos += RainDrops[i].Vel * DwarfTime.Dt; if (stormProperties.RainRandom > 0) { RainDrops[i].Vel.X += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt; RainDrops[i].Vel.Z += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt; } if (RainDrops[i].Pos.Y < 0) { RainDrops[i].IsAlive = false; } if (!RainDrops[i].IsAlive && RainDrops[i].Particle != null) { RainDrops[i].Particle.LifeRemaining = -1; RainDrops[i].Particle = null; } else if (RainDrops[i].IsAlive && RainDrops[i].Particle == null) { RainDrops[i].Particle = rainEmitter.Emitters[0].CreateParticle(RainDrops[i].Pos, RainDrops[i].Vel, Color.White); } else if (RainDrops[i].IsAlive && RainDrops[i].Particle != null) { RainDrops[i].Particle.Position = RainDrops[i].Pos; RainDrops[i].Particle.Velocity = RainDrops[i].Vel; } var test = new VoxelHandle(chunks.ChunkData, GlobalVoxelCoordinate.FromVector3(RainDrops[i].Pos)); if (!test.IsValid || test.IsEmpty || test.LiquidLevel > 0) { continue; } RainDrops[i].IsAlive = false; hitEmitter.Trigger(1, RainDrops[i].Pos + Vector3.UnitY * 0.5f, Color.White); //if (!MathFunctions.RandEvent(0.1f)) continue; var above = test.IsEmpty ? test : VoxelHelpers.GetVoxelAbove(test); if (!above.IsValid || !above.IsEmpty) { continue; } if (TypeofStorm == StormType.RainStorm && (above.LiquidLevel < WaterManager.maxWaterLevel && (above.LiquidType == LiquidType.Water))) { above.LiquidLevel = (byte)Math.Min(WaterManager.maxWaterLevel, above.LiquidLevel + WaterManager.rainFallAmount); above.LiquidType = stormProperties.LiquidToCreate; } else if (TypeofStorm == StormType.SnowStorm && above.IsEmpty && above.LiquidLevel == 0) { if (test.GrassType == 0) { test.GrassType = GrassLibrary.GetGrassType("snow").ID; test.GrassDecay = GrassLibrary.GetGrassType("snow").InitialDecayValue; } else { var existingGrass = GrassLibrary.GetGrassType((byte)test.GrassType); if (!String.IsNullOrEmpty(existingGrass.BecomeWhenSnowedOn)) { var newGrass = GrassLibrary.GetGrassType(existingGrass.BecomeWhenSnowedOn); test.GrassType = newGrass.ID; test.GrassDecay = newGrass.InitialDecayValue; } } } } Matrix tf = LocalTransform; tf.Translation += Velocity * DwarfTime.Dt; LocalTransform = tf; }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { base.Update(gameTime, chunks, camera); if (GameSettings.Current.DisableWeather) { Die(); return; } Storm.InitializeStatics(); BoundingBox box = chunks.Bounds; box.Expand(10.0f); if (GlobalTransform.Translation.X < box.Min.X || GlobalTransform.Translation.X > box.Max.X || GlobalTransform.Translation.Z < box.Min.Z || GlobalTransform.Translation.Z > box.Max.Z) { Die(); return; } bool generateRainDrop = MathFunctions.RandEvent(Raininess * 0.75f); if (generateRainDrop) { for (int i = 0; i < MaxRainDrops; i++) { if (!RainDrops[i].IsAlive) { RainDrops[i].IsAlive = true; if (RainDrops[i].Particle != null) { RainDrops[i].Particle.LifeRemaining = 60.0f; RainDrops[i].Particle.TimeAlive = 0.0f; } RainDrops[i].Pos = MathFunctions.RandVector3Box(BoundingBox.Expand(5)); RainDrops[i].Pos = new Vector3(RainDrops[i].Pos.X, BoundingBox.Min.Y - 1, RainDrops[i].Pos.Z); RainDrops[i].Vel = Vector3.Down * Storm.Properties[TypeofStorm].RainSpeed + Velocity; break; } } } bool generateLightning = LightningChance > 0.0f && MathFunctions.RandEvent((float)(LightningChance * 0.001f)); if (generateLightning) { var below = VoxelHelpers.FindFirstVoxelBelowIncludingWater(new VoxelHandle(World.ChunkManager, GlobalVoxelCoordinate.FromVector3(new Vector3(Position.X, Math.Min(World.WorldSizeInVoxels.Y - 1, Position.Y), Position.Z)))); if (below.IsValid && !below.IsEmpty) { var above = VoxelHelpers.GetVoxelAbove(below); if (above.IsValid) { EntityFactory.CreateEntity <Fire>("Fire", above.GetBoundingBox().Center()); List <Vector3> lightningStrikes = new List <Vector3>(); List <Color> colors = new List <Color>(); var c = above.GetBoundingBox().Center(); for (float t = 0; t < 1.0f; t += 0.25f) { var p = c * t + Position * (1.0f - t); lightningStrikes.Add(p + MathFunctions.RandVector3Box(-5, 5, 0, 0.1f, -5, 5)); colors.Add(Color.White); } lightningStrikes.Add(c); colors.Add(Color.White); Drawer3D.DrawLineList(lightningStrikes, colors, 0.3f); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_rain_storm_alert, MathFunctions.Rand(0.001f, 0.05f), MathFunctions.Rand(0.5f, 1.0f)); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_trap_destroyed, c, false, 1.0f, MathFunctions.Rand(-0.5f, 0.5f)); World.ParticleManager.Trigger("explode", c, Color.White, 10); } } } Storm.StormProperties stormProperties = Storm.Properties[TypeofStorm]; var rainEmitter = World.ParticleManager.Effects[stormProperties.RainEffect]; var hitEmitter = World.ParticleManager.Effects[stormProperties.HitEffect]; for (int i = 0; i < MaxRainDrops; i++) { if (!RainDrops[i].IsAlive) { continue; } RainDrops[i].Pos += RainDrops[i].Vel * DwarfTime.Dt; if (stormProperties.RainRandom > 0) { RainDrops[i].Vel.X += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt; RainDrops[i].Vel.Z += MathFunctions.Rand(-1, 1) * stormProperties.RainRandom * DwarfTime.Dt; } if (RainDrops[i].Pos.Y < 0) { RainDrops[i].IsAlive = false; } if (!RainDrops[i].IsAlive && RainDrops[i].Particle != null) { RainDrops[i].Particle.LifeRemaining = -1; } else if (RainDrops[i].IsAlive && RainDrops[i].Particle == null) { RainDrops[i].Particle = rainEmitter.Emitters[0].CreateParticle(RainDrops[i].Pos, RainDrops[i].Vel, Color.White); } else if (RainDrops[i].IsAlive && RainDrops[i].Particle != null) { RainDrops[i].Particle.Position = RainDrops[i].Pos; RainDrops[i].Particle.Velocity = RainDrops[i].Vel; } var test = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(RainDrops[i].Pos)); if (!test.IsValid || (test.IsEmpty && test.LiquidLevel == 0)) { continue; } RainDrops[i].IsAlive = false; var hitBodies = World.EnumerateIntersectingObjects(new BoundingBox(RainDrops[i].Pos - Vector3.One, RainDrops[i].Pos + Vector3.One)); foreach (var body in hitBodies) { if (body.Parent != Manager.RootComponent) { continue; } if (body.GetRoot().GetComponent <Flammable>().HasValue(out var flames)) { flames.Heat *= 0.25f; } if (body.GetRoot().GetComponent <Seedling>().HasValue(out var seeds)) { if (TypeofStorm == StormType.RainStorm) { seeds.GrowthTime += MathFunctions.Rand(1.0f, 12.0f); } else if (MathFunctions.RandEvent(0.01f)) { seeds.GetRoot().Die(); } } } hitEmitter.Trigger(1, RainDrops[i].Pos + Vector3.UnitY * 0.5f, Color.White); //if (!MathFunctions.RandEvent(0.1f)) continue; var above = test.IsEmpty ? test : VoxelHelpers.GetVoxelAbove(test); if (!above.IsValid || !above.IsEmpty) { continue; } if (TypeofStorm == StormType.RainStorm && (above.LiquidLevel < WaterManager.maxWaterLevel && (above.LiquidType == LiquidType.Water))) { above.LiquidLevel = (byte)Math.Min(WaterManager.maxWaterLevel, above.LiquidLevel + WaterManager.rainFallAmount); above.LiquidType = stormProperties.LiquidToCreate; } else if (TypeofStorm == StormType.SnowStorm && above.IsEmpty && above.LiquidLevel == 0) { if (test.GrassType == 0) { test.GrassType = Library.GetGrassType("snow").ID; test.GrassDecay = Library.GetGrassType("snow").InitialDecayValue; } else { var existingGrass = Library.GetGrassType((byte)test.GrassType); if (!String.IsNullOrEmpty(existingGrass.BecomeWhenSnowedOn)) { var newGrass = Library.GetGrassType(existingGrass.BecomeWhenSnowedOn); test.GrassType = newGrass.ID; test.GrassDecay = newGrass.InitialDecayValue; } } } } Matrix tf = LocalTransform; tf.Translation += Velocity * DwarfTime.Dt; LocalTransform = tf; }