public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (IsExtinct) { base.OnAsyncClientParticleTick(manager, pos, windAffectednessAtPos, secondsTicking); return; } BlockEntityKiln bef = manager.BlockAccess.GetBlockEntity(pos) as BlockEntityKiln; if (bef != null && bef.CurrentModel == EnumKilnModel.Smelting) { for (int i = 0; i < ringParticles.Length; i++) { AdvancedParticleProperties bps = ringParticles[i]; bps.WindAffectednesAtPos = windAffectednessAtPos; bps.basePos.X = pos.X + basePos[i].X; bps.basePos.Y = pos.Y + basePos[i].Y; bps.basePos.Z = pos.Z + basePos[i].Z; manager.Spawn(bps); } return; } base.OnAsyncClientParticleTick(manager, pos, windAffectednessAtPos, secondsTicking); }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (api.World.Rand.NextDouble() > particleQuantity) { return; } AdvancedParticleProperties bps = ParticleProperties[0]; bps.basePos.X = pos.X; bps.basePos.Y = pos.Y; bps.basePos.Z = pos.Z; bps.Velocity[0].avg = (float)PushVector.X * 500; bps.Velocity[1].avg = (float)PushVector.Y * 500; bps.Velocity[2].avg = (float)PushVector.Z * 500; bps.GravityEffect.avg = 0.5f; bps.HsvaColor[3].avg = 180 * Math.Min(1, secondsTicking / 7f); bps.Quantity.avg = 1; bps.PosOffset[1].avg = 2 / 16f; bps.PosOffset[1].var = LiquidLevel / 8f * 0.75f; bps.SwimOnLiquid = true; manager.Spawn(bps); }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (ParticleProperties != null && ParticleProperties.Length > 0) { int rnd = GameMath.MurmurHash3Mod(pos.X, pos.Y, pos.Z, 4); Vec3f[] poses = candleWickPositionsByRot[rnd]; for (int i = 0; i < ParticleProperties.Length; i++) { AdvancedParticleProperties bps = ParticleProperties[i]; bps.WindAffectednesAtPos = windAffectednessAtPos; for (int j = 0; j < QuantityCandles; j++) { Vec3f dp = poses[j]; bps.basePos.X = pos.X + dp.X; bps.basePos.Y = pos.Y + dp.Y; bps.basePos.Z = pos.Z + dp.Z; manager.Spawn(bps); } } } }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (ParticleProperties != null && ParticleProperties.Length > 0) { for (int i = 0; i < 4; i++) { if (api.World.Rand.NextDouble() > particleQuantity) { continue; } BlockFacing facing = BlockFacing.HORIZONTALS[i]; Block block = manager.BlockAccess.GetBlock(pos.X + facing.Normali.X, pos.Y, pos.Z + facing.Normali.Z); if (block.IsLiquid() || block.SideSolid[facing.Opposite.Index]) { continue; } AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = pos.X + TopMiddlePos.X; bps.basePos.Y = pos.Y; bps.basePos.Z = pos.Z + TopMiddlePos.Z; bps.WindAffectednes = windAffectednessAtPos * 0.25f; bps.HsvaColor[3].avg = 180 * Math.Min(1, secondsTicking / 7f); bps.Quantity.avg = 1; bps.Velocity[1].avg = -0.4f; manager.Spawn(bps); } } }
private void SpawnSnowParticles(IAsyncParticleManager manager, WeatherDataSnapshot weatherData, ClimateCondition conds, EntityPos plrPos, float plevel) { snowParticle.WindAffected = true; snowParticle.WindAffectednes = 1f; float wetness = 2.5f * GameMath.Clamp(ws.clientClimateCond.Temperature + 1, 0, 4) / 4f; float dx = (float)(plrPos.Motion.X * 40) - (30 - 9 * wetness) * 2 * weatherData.curWindSpeed.X; float dy = (float)(plrPos.Motion.Y * 40); float dz = (float)(plrPos.Motion.Z * 40); snowParticle.MinVelocity.Set(-0.5f + 5 * weatherData.curWindSpeed.X, -1f, -0.5f); snowParticle.AddVelocity.Set(1f + 5 * weatherData.curWindSpeed.X, 0.05f, 1f); snowParticle.Color = ColorUtil.ToRgba(255, 255, 255, 255); snowParticle.MinQuantity = 100 * plevel * (1 + wetness / 3); snowParticle.AddQuantity = 25 * plevel * (1 + wetness / 3); snowParticle.ParentVelocity = parentVeloSnow; snowParticle.ShouldDieInLiquid = true; snowParticle.LifeLength = Math.Max(1f, 4f - wetness); snowParticle.Color = ColorUtil.ColorOverlay(ColorUtil.ToRgba(255, 255, 255, 255), rainParticle.Color, wetness / 4f); snowParticle.GravityEffect = 0.005f * (1 + 20 * wetness); snowParticle.MinSize = 0.1f * conds.Rainfall; snowParticle.MaxSize = 0.3f * conds.Rainfall / (1 + wetness); float hrange = 40; float vrange = 23; snowParticle.MinPos.Set(particlePos.X - hrange + dx, particlePos.Y + vrange + dy, particlePos.Z - hrange + dz); snowParticle.AddPos.Set(2 * hrange + dx, -0.66f * vrange + dy, 2 * hrange + dz); manager.Spawn(snowParticle); }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { double rand = random.NextDouble() * 50d; if (rand > 1d) { return; } double rainLevel = ((WeatherSystemClient)weatherSystem).GetActualRainLevel(pos, true); IBlockAccessor accessor = manager.BlockAccess; double count = 1d; count += accessor.GetBlock(pos.NorthCopy()) is BlockSticksLayer ? 0.25 : 0; count += accessor.GetBlock(pos.SouthCopy()) is BlockSticksLayer ? 0.25 : 0; count += accessor.GetBlock(pos.WestCopy()) is BlockSticksLayer ? 0.25 : 0; count += accessor.GetBlock(pos.EastCopy()) is BlockSticksLayer ? 0.25 : 0; // Reduced drips if similar blocks adjacent, otherwise there can be a lot of drops on a large roof if (rainLevel > rand * count) { waterParticles.MinPos.Set(pos.X, pos.Y - 0.05, pos.Z); manager.Spawn(waterParticles); } }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (api.World.Rand.NextDouble() < 0.98 - GlobalConstants.CurrentWindSpeedClient.X / 10f) { return; } var be = api.World.BlockAccessor.GetBlockEntity(pos) as BlockEntityFruitTreePart; if (be?.LeafParticlesColor == null) { return; } if (be.FruitTreeState == EnumFruitTreeState.EnterDormancy) { foliageParticles.Color = be.LeafParticlesColor[api.World.Rand.Next(25)]; foliageParticles.Color = (api as ICoreClientAPI).World.ApplyColorMapOnRgba("climatePlantTint", SeasonColorMap, foliageParticles.Color, pos.X, pos.Y, pos.Z); foliageParticles.GravityEffect = 0.02f + 0.005f * GlobalConstants.CurrentWindSpeedClient.X; foliageParticles.MinSize = 0.4f; } else { foliageParticles.Color = be.BlossomParticlesColor[api.World.Rand.Next(25)]; foliageParticles.MinSize = 0.1f; foliageParticles.GravityEffect = 0.005f + 0.005f * GlobalConstants.CurrentWindSpeedClient.X; } foliageParticles.LifeLength = 7f - GlobalConstants.CurrentWindSpeedClient.X * 3f; foliageParticles.WindAffectednes = 1f; foliageParticles.MinPos.Set(pos); manager.Spawn(foliageParticles); }
private void SpawnHailParticles(IAsyncParticleManager manager, WeatherDataSnapshot weatherData, ClimateCondition conds, EntityPos plrPos, float plevel) { float dx = (float)(plrPos.Motion.X * 40) - 4 * weatherData.curWindSpeed.X; float dy = (float)(plrPos.Motion.Y * 40); float dz = (float)(plrPos.Motion.Z * 40); hailParticle.MinPos.Set(particlePos.X + dx, particlePos.Y + 15 + dy, particlePos.Z + dz); hailParticle.MinSize = 0.3f * (0.5f + conds.Rainfall); // * weatherData.PrecParticleSize; hailParticle.MaxSize = 1f * (0.5f + conds.Rainfall); // * weatherData.PrecParticleSize; //hailParticle.AddPos.Set(80, 5, 80); hailParticle.Color = ColorUtil.ToRgba(220, 210, 230, 255); hailParticle.MinQuantity = 100 * plevel; hailParticle.AddQuantity = 25 * plevel; hailParticle.MinVelocity.Set(-0.025f + 7.5f * weatherData.curWindSpeed.X, -5f, -0.025f); hailParticle.AddVelocity.Set(0.05f + 7.5f * weatherData.curWindSpeed.X, 0.05f, 0.05f); manager.Spawn(hailParticle); }
public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking) { if (ParticleProperties != null && ParticleProperties.Length > 0) { for (int i = 0; i < 4; i++) { if (api.World.Rand.NextDouble() > particleQuantity) { continue; } BlockFacing facing = BlockFacing.HORIZONTALS[i]; Block block = manager.BlockAccess.GetBlock(pos.X + facing.Normali.X, pos.Y, pos.Z + facing.Normali.Z); if (block.IsLiquid() || block.SideSolid[facing.Opposite.Index]) { continue; } AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = pos.X + TopMiddlePos.X; bps.basePos.Y = pos.Y; bps.basePos.Z = pos.Z + TopMiddlePos.Z; bps.WindAffectednes = windAffectednessAtPos * 0.25f; bps.HsvaColor[3].avg = 180 * Math.Min(1, secondsTicking / 7f); bps.Quantity.avg = 1; bps.Velocity[1].avg = -0.4f; bps.Velocity[0].avg = API.Config.GlobalConstants.CurrentWindSpeedClient.X * windAffectednessAtPos; bps.Velocity[2].avg = API.Config.GlobalConstants.CurrentWindSpeedClient.Z * windAffectednessAtPos; bps.Size.avg = 0.05f; bps.Size.var = 0f; bps.SizeEvolve = EvolvingNatFloat.create(EnumTransformFunction.LINEAR, 0.8f); manager.Spawn(bps); } } }
public virtual void RenderParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking, AdvancedParticleProperties[] particles) { if (this.fuelBurnTime < 3) { return; } int logsCount = FuelSlot.StackSize; bool fireFull = logsCount > 3; //fireFull means it's a fire with 2 rows of logs (between 4 and 6 logs) - flames will start higher double[] x = new double[4]; float[] z = new float[4]; for (int i = 0; i < particles.Length; i++) { //reduced number of bright yellow flames - and reduces as the fuel burns if (i >= 12 && prng.Next(0, 90) > this.fuelBurnTime) { continue; } //limit orange flames when fuel is almost burned if (i >= 8 && i < 12 && prng.Next(0, 12) > this.fuelBurnTime) { continue; } //also randomise red flames if (i >= 4 && i < 4 && prng.Next(0, 6) == 0) { continue; } //adjust flames to the number of logs, if less than 3 logs if (i >= 4 && logsCount < 3) { bool rotated = this.rotation >= 180; if (!rotated && z[i % 2] > logsCount * 0.2f + 0.14f) { continue; } if (rotated && z[i % 2] < (3 - logsCount) * 0.2f + 0.14f) { continue; } } AdvancedParticleProperties bps = particles[i]; bps.WindAffectednesAtPos = 0f; bps.basePos.X = pos.X; bps.basePos.Y = pos.Y + (fireFull ? 3 / 32f : 1 / 32f); bps.basePos.Z = pos.Z; //i >= 4 is flames; i < 4 is smoke if (i >= 4) { bool rotate = this.rotation % 180 > 0; if (fireFull) { rotate = !rotate; } bps.basePos.Z += rotate ? x[i % 2] : z[i % 2]; bps.basePos.X += rotate ? z[i % 2] : x[i % 2]; bps.basePos.Y += (fireFull ? 4 : 3) / 32f; switch (this.rotation) { case 0: bps.basePos.X -= fireFull ? 0.08f : 0.12f; break; case 180: bps.basePos.X += fireFull ? 0.08f : 0.12f; break; case 90: bps.basePos.Z += fireFull ? 0.08f : 0.12f; break; default: bps.basePos.Z -= fireFull ? 0.08f : 0.12f; break; } } else //set up flame positions with RNG (this way all three flame evolution particles will be in approx. same position) { x[i] = prng.NextDouble() * 0.4f + 0.33f; // the multiplier and offset gets the flame position aligned with the top surface of the logs z[i] = 0.26f + prng.Next(0, 3) * 0.2f + (float)prng.NextDouble() * 0.08f; } manager.Spawn(bps); } }
private bool asyncParticleSpawn(float dt, IAsyncParticleManager manager) { int alive = manager.ParticlesAlive(EnumParticleModel.Quad); // Reduce particle spawn the more falling blocks there are // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIwLjk1Xih4LzUpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMCIsIjIwMCIsIjAiLCIxIl19XQ-- float particlemul = Math.Max(0.05f, (float)Math.Pow(0.95f, alive / 200f)); foreach (var bef in fallingBlocks) { //if (api.Side == EnumAppSide.Server || dustIntensity == 0) return; float smokeAdd = 0f; if (bef.nowImpacted) { smokeAdd = 20f; bef.nowImpacted = false; } if (bef.Block.Id != 0) { dustParticles.Color = bef.Block.GetRandomColor(capi, bef.blockAsStack); dustParticles.Color &= 0xffffff; dustParticles.Color |= (150 << 24); dustParticles.MinPos.Set(bef.Pos.X - 0.2 - 0.5, bef.Pos.Y, bef.Pos.Z - 0.2 - 0.5); dustParticles.MinSize = 1f; float veloMul = smokeAdd / 20f; dustParticles.MinVelocity.Set(-0.2f * veloMul, 1f * (float)bef.Pos.Motion.Y, -0.2f * veloMul); dustParticles.AddVelocity.Set(0.4f * veloMul, 0.2f * (float)bef.Pos.Motion.Y + -veloMul, 0.4f * veloMul); dustParticles.MinQuantity = smokeAdd * bef.dustIntensity * particlemul / 2f; dustParticles.AddQuantity = (6 * Math.Abs((float)bef.Pos.Motion.Y) + smokeAdd) * bef.dustIntensity * particlemul / 2f; manager.Spawn(dustParticles); } bitsParticles.MinPos.Set(bef.Pos.X - 0.2 - 0.5, bef.Pos.Y - 0.5, bef.Pos.Z - 0.2 - 0.5); bitsParticles.MinVelocity.Set(-2f, 30f * (float)bef.Pos.Motion.Y, -2f); bitsParticles.AddVelocity.Set(4f, 0.2f * (float)bef.Pos.Motion.Y, 4f); bitsParticles.MinQuantity = particlemul; bitsParticles.AddQuantity = 6 * Math.Abs((float)bef.Pos.Motion.Y) * particlemul; bitsParticles.Color = dustParticles.Color; capi.World.SpawnParticles(bitsParticles); } int cnt = toRegister.Count; while (cnt-- > 0) { if (toRegister.TryDequeue(out EntityBlockFalling bef)) { fallingBlocks.Add(bef); } } cnt = toRemove.Count; while (cnt-- > 0) { if (toRemove.TryDequeue(out EntityBlockFalling bef)) { fallingBlocks.Remove(bef); } } return(true); }
private void SpawnRainParticles(IAsyncParticleManager manager, WeatherDataSnapshot weatherData, ClimateCondition conds, EntityPos plrPos, float plevel, int onwaterSplashParticleColor) { float dx = (float)(plrPos.Motion.X * 80); float dy = (float)(plrPos.Motion.Y * 80); float dz = (float)(plrPos.Motion.Z * 80); rainParticle.MinPos.Set(particlePos.X - 30 + dx, particlePos.Y + 15 + dy, particlePos.Z - 30 + dz); rainParticle.WithTerrainCollision = false; rainParticle.MinQuantity = 1000 * plevel; rainParticle.LifeLength = 1f; rainParticle.AddQuantity = 25 * plevel; rainParticle.MinSize = 0.15f * (0.5f + conds.Rainfall); // * weatherData.PrecParticleSize; rainParticle.MaxSize = 0.22f * (0.5f + conds.Rainfall); // weatherData.PrecParticleSize; rainParticle.Color = rainParticleColor; rainParticle.MinVelocity.Set(-0.025f + 8 * weatherData.curWindSpeed.X, -10f, -0.025f); rainParticle.AddVelocity.Set(0.05f + 8 * weatherData.curWindSpeed.X, 0.05f, 0.05f); manager.Spawn(rainParticle); splashParticles.MinVelocity = new Vec3f(-1f, 3, -1f); splashParticles.AddVelocity = new Vec3f(2, 0, 2); splashParticles.LifeLength = 0.1f; splashParticles.MinSize = 0.07f * (0.5f + 0.65f * conds.Rainfall); // weatherData.PrecParticleSize; splashParticles.MaxSize = 0.2f * (0.5f + 0.65f * conds.Rainfall); // weatherData.PrecParticleSize; splashParticles.ShouldSwimOnLiquid = true; splashParticles.Color = rainParticleColor; float cnt = 100 * plevel; for (int i = 0; i < cnt; i++) { double px = particlePos.X + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); double pz = particlePos.Z + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); int py = capi.World.BlockAccessor.GetRainMapHeightAt((int)px, (int)pz); Block block = capi.World.BlockAccessor.GetLiquidBlock((int)px, py, (int)pz); if (block.IsLiquid()) { splashParticles.MinPos.Set(px, py + block.TopMiddlePos.Y - 1 / 8f, pz); splashParticles.AddVelocity.Y = 1.5f; splashParticles.LifeLength = 0.17f; splashParticles.Color = onwaterSplashParticleColor; } else { if (block.BlockId == 0) { block = capi.World.BlockAccessor.GetBlock((int)px, py, (int)pz); // block read from LiquidsLayer could be ice, in which case no need to read from the physical blocks layer } double b = 0.75 + 0.25 * rand.NextDouble(); int ca = 230 - rand.Next(100); int cr = (int)(((rainParticleColor >> 16) & 0xff) * b); int cg = (int)(((rainParticleColor >> 8) & 0xff) * b); int cb = (int)(((rainParticleColor >> 0) & 0xff) * b); splashParticles.Color = (ca << 24) | (cr << 16) | (cg << 8) | cb; splashParticles.AddVelocity.Y = 0f; splashParticles.LifeLength = 0.1f; splashParticles.MinPos.Set(px, py + block.TopMiddlePos.Y + 0.05, pz); } manager.Spawn(splashParticles); } }
private void SpawnDustParticles(IAsyncParticleManager manager, WeatherDataSnapshot weatherData, EntityPos plrPos, float dryness, int onwaterSplashParticleColor) { float dx = (float)(plrPos.Motion.X * 40) - 50 * weatherData.curWindSpeed.X; float dy = (float)(plrPos.Motion.Y * 40); float dz = (float)(plrPos.Motion.Z * 40); double range = 40; // Particles are less visible during fog so we can abuse the situation to make it more particle rich float rangReduction = 1 - targetFogDensity; range *= rangReduction; stormDustParticles.MinPos.Set(particlePos.X - range + dx, particlePos.Y + 5 + 5 * Math.Abs(weatherData.curWindSpeed.X) + dy, particlePos.Z - range + dz); stormDustParticles.AddPos.Set(2 * range, -20, 2 * range); stormDustParticles.GravityEffect = 0.1f; stormDustParticles.ParticleModel = EnumParticleModel.Quad; stormDustParticles.LifeLength = 1f; stormDustParticles.DieOnRainHeightmap = true; stormDustParticles.WindAffectednes = 8f; stormDustParticles.MinQuantity = 0; stormDustParticles.AddQuantity = 8 * (weatherData.curWindSpeed.X - 0.5f) * dryness; stormDustParticles.MinSize = 0.1f; stormDustParticles.MaxSize = 0.4f; stormDustParticles.MinVelocity.Set(-0.025f + 10 * weatherData.curWindSpeed.X, 0f, -0.025f); stormDustParticles.AddVelocity.Set(0.05f + 4 * weatherData.curWindSpeed.X, -0.25f, 0.05f); for (int i = 0; i < dustParticlesPerTick; i++) { double px = particlePos.X + dx + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); double pz = particlePos.Z + dz + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); int py = capi.World.BlockAccessor.GetRainMapHeightAt((int)px, (int)pz); Block block = capi.World.BlockAccessor.GetBlock((int)px, py, (int)pz); if (block.Id == 0) { continue; } if (capi.World.BlockAccessor.GetLiquidBlock((int)px, py, (int)pz).Id != 0) { continue; // Liquid surface or ice produces no particles } if (block.BlockMaterial != EnumBlockMaterial.Sand && block.BlockMaterial != EnumBlockMaterial.Snow) { if (rand.NextDouble() < 0.5f) { continue; } } if (block.BlockMaterial == EnumBlockMaterial.Sand) { sandFinds++; sandCountByBlock[indicesBySandBlockId[block.Id]]++; } if (Math.Abs(py - particlePos.Y) > 15) { continue; } tmpPos.Set((int)px, py, (int)pz); stormDustParticles.Color = ColorUtil.ReverseColorBytes(block.GetColor(capi, tmpPos)); stormDustParticles.Color |= 255 << 24; manager.Spawn(stormDustParticles); } spawnCount++; if (weatherData.curWindSpeed.X > 0.85f) { stormWaterParticles.AddVelocity.Y = 1.5f; stormWaterParticles.LifeLength = 0.17f; stormWaterParticles.WindAffected = true; stormWaterParticles.WindAffectednes = 1f; stormWaterParticles.GravityEffect = 0.4f; stormWaterParticles.MinVelocity.Set(-0.025f + 4 * weatherData.curWindSpeed.X, 1.5f, -0.025f); stormWaterParticles.Color = onwaterSplashParticleColor; //stormWaterParticles.Color |= 140 << 24; stormWaterParticles.MinQuantity = 1; stormWaterParticles.AddQuantity = 5; stormWaterParticles.ShouldDieInLiquid = false; splashParticles.WindAffected = true; splashParticles.WindAffectednes = 1f; for (int i = 0; i < 20; i++) { double px = particlePos.X + (rand.NextDouble() * rand.NextDouble()) * 40 * (1 - 2 * rand.Next(2)); double pz = particlePos.Z + (rand.NextDouble() * rand.NextDouble()) * 40 * (1 - 2 * rand.Next(2)); int py = capi.World.BlockAccessor.GetRainMapHeightAt((int)px, (int)pz); Block block = capi.World.BlockAccessor.GetLiquidBlock((int)px, py, (int)pz); if (!block.IsLiquid()) { continue; } stormWaterParticles.MinPos.Set(px, py + block.TopMiddlePos.Y, pz); stormWaterParticles.ParticleModel = EnumParticleModel.Cube; stormWaterParticles.MinSize = 0.4f; manager.Spawn(stormWaterParticles); splashParticles.MinPos.Set(px, py + block.TopMiddlePos.Y - 1 / 8f, pz); splashParticles.MinVelocity.X = weatherData.curWindSpeed.X * 1.5f; splashParticles.AddVelocity.Y = 1.5f; splashParticles.LifeLength = 0.17f; splashParticles.Color = onwaterSplashParticleColor; manager.Spawn(splashParticles); } } }
private static bool SpawnParticleAsync(float dt, IAsyncParticleManager manager) { var weatherData = _ws.BlendedWeatherData; var conds = _ws.clientClimateCond; if (conds == null || !_ws.playerChunkLoaded) { return(true); } EntityPos plrPos = Api.World.Player.Entity.Pos; var precIntensity = conds.Rainfall; var plevel = precIntensity * Api.Settings.Int["particleLevel"] / 100f; _tmpPos.Set((int)plrPos.X, (int)plrPos.Y, (int)plrPos.Z); var precType = weatherData.BlendedPrecType; if (precType == EnumPrecipitationType.Auto) { precType = conds.Temperature < weatherData.snowThresholdTemp ? EnumPrecipitationType.Snow : EnumPrecipitationType.Rain; } _particlePos.Set(Api.World.Player.Entity.Pos.X, Api.World.Player.Entity.Pos.Y, Api.World.Player.Entity.Pos.Z); var onwaterSplashParticleColor = Api.World.ApplyColorMapOnRgba(_lblock.ClimateColorMapForMap, _lblock.SeasonColorMapForMap, ColorUtil.WhiteArgb, (int)_particlePos.X, (int)_particlePos.Y, (int)_particlePos.Z, false); var col = ColorUtil.ToBGRABytes(onwaterSplashParticleColor); onwaterSplashParticleColor = ColorUtil.ToRgba(94, col[0], col[1], col[2]); _centerPos.Set((int)_particlePos.X, 0, (int)_particlePos.Z); for (var lx = 0; lx < 16; lx++) { var dx = (lx - 8) * 4; for (var lz = 0; lz < 16; lz++) { var dz = (lz - 8) * 4; _lowResRainHeightMap[lx, lz] = Api.World.BlockAccessor.GetRainMapHeightAt(_centerPos.X + dx, _centerPos.Z + dz); } } var rainYPos = Api.World.BlockAccessor.GetRainMapHeightAt((int)_particlePos.X, (int)_particlePos.Z); _parentVeloSnow.X = -Math.Max(0, weatherData.curWindSpeed.X / 2 - 0.15f); _parentVeloSnow.Y = 0; _parentVeloSnow.Z = 0; if (weatherData.curWindSpeed.X > 0.7f && _particlePos.Y - rainYPos < 10) { var dx = (float)(plrPos.Motion.X * 40) - 50 * weatherData.curWindSpeed.X; var dy = (float)(plrPos.Motion.Y * 40); var dz = (float)(plrPos.Motion.Z * 40); _dustParticles.MinPos.Set(_particlePos.X - 40 + dx, _particlePos.Y + 15 + dy, _particlePos.Z - 40 + dz); _dustParticles.AddPos.Set(80, -20, 80); _dustParticles.GravityEffect = -0.1f - (float)_rand.NextDouble() * 0.1f; _dustParticles.ParticleModel = EnumParticleModel.Quad; _dustParticles.LifeLength = 1f; _dustParticles.DieOnRainHeightmap = true; _dustParticles.WindAffectednes = 8f; _dustParticles.MinQuantity = 0; _dustParticles.AddQuantity = 6 * (weatherData.curWindSpeed.X - 0.7f); _dustParticles.MinSize = 0.1f; _dustParticles.MaxSize = 0.4f; _dustParticles.MinVelocity.Set(-0.025f + 8 * weatherData.curWindSpeed.X, -0.2f, -0.025f); _dustParticles.AddVelocity.Set(0.05f + 4 * weatherData.curWindSpeed.X, 0.05f, 0.05f); for (var i = 0; i < 6; i++) { var px = _particlePos.X + dx + _rand.NextDouble() * _rand.NextDouble() * 60 * (1 - 2 * _rand.Next(2)); var pz = _particlePos.Z + dz + _rand.NextDouble() * _rand.NextDouble() * 60 * (1 - 2 * _rand.Next(2)); var py = Api.World.BlockAccessor.GetRainMapHeightAt((int)px, (int)pz); var block = Api.World.BlockAccessor.GetBlock((int)px, py, (int)pz); if (block.IsLiquid()) { continue; } _tmpPos.Set((int)px, py, (int)pz); _dustParticles.Color = ColorUtil.ReverseColorBytes(block.GetColor(Api, _tmpPos)); _dustParticles.Color |= 255 << 24; manager.Spawn(_dustParticles); } } if (precIntensity <= 0.02) { return(true); } if (Settings.AllowHail && precType == EnumPrecipitationType.Hail) { var dx = (float)(plrPos.Motion.X * 40) - 4 * weatherData.curWindSpeed.X; var dy = (float)(plrPos.Motion.Y * 40); var dz = (float)(plrPos.Motion.Z * 40); _hailParticle.MinPos.Set(_particlePos.X + dx, _particlePos.Y + 15 + dy, _particlePos.Z + dz); _hailParticle.MinSize = 0.3f * (0.5f + conds.Rainfall); _hailParticle.MaxSize = 1f * (0.5f + conds.Rainfall); _hailParticle.Color = ColorUtil.ToRgba(220, 210, 230, 255); _hailParticle.MinQuantity = 100 * plevel; _hailParticle.AddQuantity = 25 * plevel; _hailParticle.MinVelocity.Set(-0.025f + 7.5f * weatherData.curWindSpeed.X, -5f, -0.025f); _hailParticle.AddVelocity.Set(0.05f + 7.5f * weatherData.curWindSpeed.X, 0.05f, 0.05f); manager.Spawn(_hailParticle); return(true); } if (Settings.AllowRain && precType == EnumPrecipitationType.Rain) { var dx = (float)(plrPos.Motion.X * 80); var dy = (float)(plrPos.Motion.Y * 80); var dz = (float)(plrPos.Motion.Z * 80); _rainParticle.MinPos.Set(_particlePos.X - 30 + dx, _particlePos.Y + 15 + dy, _particlePos.Z - 30 + dz); _rainParticle.WithTerrainCollision = false; _rainParticle.MinQuantity = 1000 * plevel; _rainParticle.LifeLength = 1f; _rainParticle.AddQuantity = 25 * plevel; _rainParticle.MinSize = 0.15f * (0.5f + conds.Rainfall); _rainParticle.MaxSize = 0.22f * (0.5f + conds.Rainfall); _rainParticle.Color = _rainParticleColor; _rainParticle.MinVelocity.Set(-0.025f + 8 * weatherData.curWindSpeed.X, -10f, -0.025f); _rainParticle.AddVelocity.Set(0.05f + 8 * weatherData.curWindSpeed.X, 0.05f, 0.05f); manager.Spawn(_rainParticle); _splashParticles.MinVelocity = new Vec3f(-1f, 3, -1f); _splashParticles.AddVelocity = new Vec3f(2, 0, 2); _splashParticles.LifeLength = 0.1f; _splashParticles.MinSize = 0.07f * (0.5f + 0.65f * conds.Rainfall); _splashParticles.MaxSize = 0.2f * (0.5f + 0.65f * conds.Rainfall); _splashParticles.ShouldSwimOnLiquid = true; _splashParticles.Color = _rainParticleColor; var cnt = 100 * plevel; for (var i = 0; i < cnt; i++) { var px = _particlePos.X + _rand.NextDouble() * _rand.NextDouble() * 60 * (1 - 2 * _rand.Next(2)); var pz = _particlePos.Z + _rand.NextDouble() * _rand.NextDouble() * 60 * (1 - 2 * _rand.Next(2)); var py = Api.World.BlockAccessor.GetRainMapHeightAt((int)px, (int)pz); var block = Api.World.BlockAccessor.GetBlock((int)px, py, (int)pz); if (block.IsLiquid()) { _splashParticles.MinPos.Set(px, py + block.TopMiddlePos.Y - 1 / 8f, pz); _splashParticles.AddVelocity.Y = 1.5f; _splashParticles.LifeLength = 0.17f; _splashParticles.Color = onwaterSplashParticleColor; } else { var b = 0.75 + 0.25 * _rand.NextDouble(); var ca = 230 - _rand.Next(100); var cr = (int)(((_rainParticleColor >> 16) & 0xff) * b); var cg = (int)(((_rainParticleColor >> 8) & 0xff) * b); var cb = (int)(((_rainParticleColor >> 0) & 0xff) * b); _splashParticles.Color = (ca << 24) | (cr << 16) | (cg << 8) | cb; _splashParticles.AddVelocity.Y = 0f; _splashParticles.LifeLength = 0.1f; _splashParticles.MinPos.Set(px, py + block.TopMiddlePos.Y + 0.05, pz); } manager.Spawn(_splashParticles); } } if (Settings.AllowSnow && precType == EnumPrecipitationType.Snow) { var wetness = 2.5f * GameMath.Clamp(_ws.clientClimateCond.Temperature + 1, 0, 4) / 4f; var dx = (float)(plrPos.Motion.X * 40) - (30 - 9 * wetness) * weatherData.curWindSpeed.X; var dy = (float)(plrPos.Motion.Y * 40); var dz = (float)(plrPos.Motion.Z * 40); _snowParticle.MinVelocity.Set(-0.5f + 5 * weatherData.curWindSpeed.X, -1f, -0.5f); _snowParticle.AddVelocity.Set(1f + 5 * weatherData.curWindSpeed.X, 0.05f, 1f); _snowParticle.Color = ColorUtil.ToRgba(255, 255, 255, 255); _snowParticle.MinQuantity = 90 * plevel * (1 + wetness / 3); _snowParticle.AddQuantity = 15 * plevel * (1 + wetness / 3); _snowParticle.ParentVelocity = _parentVeloSnow; _snowParticle.ShouldDieInLiquid = true; _snowParticle.LifeLength = Math.Max(1f, 4f - wetness); _snowParticle.Color = ColorUtil.ColorOverlay(ColorUtil.ToRgba(255, 255, 255, 255), _rainParticle.Color, wetness / 4f); _snowParticle.GravityEffect = 0.005f * (1 + 20 * wetness); _snowParticle.MinSize = 0.1f * conds.Rainfall; _snowParticle.MaxSize = 0.3f * conds.Rainfall / (1 + wetness); const float hrange = 40f; const float vrange = 20f; _snowParticle.MinPos.Set(_particlePos.X - hrange + dx, _particlePos.Y + vrange + dy, _particlePos.Z - hrange + dz); _snowParticle.AddPos.Set(2 * hrange + dx, -0.66f * vrange + dy, 2 * hrange + dz); manager.Spawn(_snowParticle); } return(true); }
private bool asyncParticleSpawn(float dt, IAsyncParticleManager manager) { WeatherDataSnapshot weatherData = ws.BlendedWeatherData; ClimateCondition conds = ws.clientClimateCond; if (conds == null || !ws.playerChunkLoaded) { return(true); } EntityPos plrPos = capi.World.Player.Entity.Pos; float precIntensity = conds.Rainfall; float plevel = precIntensity * capi.Settings.Int["particleLevel"] / 100f; tmpPos.Set((int)plrPos.X, (int)plrPos.Y, (int)plrPos.Z); //float plevel = weatherData.PrecIntensity * capi.Settings.Int["particleLevel"] / 100f; EnumPrecipitationType precType = weatherData.BlendedPrecType; if (precType == EnumPrecipitationType.Auto) { precType = conds.Temperature < weatherData.snowThresholdTemp ? EnumPrecipitationType.Snow : EnumPrecipitationType.Rain; } particlePos.Set(capi.World.Player.Entity.Pos.X, capi.World.Player.Entity.Pos.Y, capi.World.Player.Entity.Pos.Z); int onwaterSplashParticleColor = capi.World.ApplyColorMapOnRgba(lblock.ClimateColorMapForMap, lblock.SeasonColorMapForMap, ColorUtil.WhiteArgb, (int)particlePos.X, (int)particlePos.Y, (int)particlePos.Z, false); byte[] col = ColorUtil.ToBGRABytes(onwaterSplashParticleColor); onwaterSplashParticleColor = ColorUtil.ToRgba(94, col[0], col[1], col[2]); centerPos.Set((int)particlePos.X, 0, (int)particlePos.Z); for (int lx = 0; lx < 16; lx++) { int dx = (lx - 8) * 4; for (int lz = 0; lz < 16; lz++) { int dz = (lz - 8) * 4; lowResRainHeightMap[lx, lz] = capi.World.BlockAccessor.GetRainMapHeightAt(centerPos.X + dx, centerPos.Z + dz); } } int rainYPos = capi.World.BlockAccessor.GetRainMapHeightAt((int)particlePos.X, (int)particlePos.Z); parentVeloSnow.X = -Math.Max(0, weatherData.curWindSpeed.X / 2 - 0.15f); parentVeloSnow.Y = 0; parentVeloSnow.Z = 0; // Don't spawn if wind speed below 70% or if the player is 10 blocks above ground if (weatherData.curWindSpeed.X > 0.7f && particlePos.Y - rainYPos < 10) { float dx = (float)(plrPos.Motion.X * 40) - 50 * weatherData.curWindSpeed.X; float dy = (float)(plrPos.Motion.Y * 40); float dz = (float)(plrPos.Motion.Z * 40); dustParticles.MinPos.Set(particlePos.X - 40 + dx, particlePos.Y + 15 + dy, particlePos.Z - 40 + dz); dustParticles.AddPos.Set(80, -20, 80); dustParticles.GravityEffect = -0.1f - (float)rand.NextDouble() * 0.1f; dustParticles.ParticleModel = EnumParticleModel.Quad; dustParticles.LifeLength = 1f; dustParticles.DieOnRainHeightmap = true; dustParticles.WindAffectednes = 8f; dustParticles.MinQuantity = 0; dustParticles.AddQuantity = 6 * (weatherData.curWindSpeed.X - 0.7f); dustParticles.MinSize = 0.1f; dustParticles.MaxSize = 0.4f; dustParticles.MinVelocity.Set(-0.025f + 8 * weatherData.curWindSpeed.X, -0.2f, -0.025f); dustParticles.AddVelocity.Set(0.05f + 4 * weatherData.curWindSpeed.X, 0.05f, 0.05f); for (int i = 0; i < 6; i++) { double px = particlePos.X + dx + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); double pz = particlePos.Z + dz + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); int py = capi.World.BlockAccessor.GetRainMapHeightAt((int)px, (int)pz); Block block = capi.World.BlockAccessor.GetBlock((int)px, py, (int)pz); if (block.IsLiquid()) { continue; } tmpPos.Set((int)px, py, (int)pz); dustParticles.Color = ColorUtil.ReverseColorBytes(block.GetColor(capi, tmpPos)); dustParticles.Color |= 255 << 24; manager.Spawn(dustParticles); } } if (precIntensity <= 0.02) { return(true); } if (precType == EnumPrecipitationType.Hail) { float dx = (float)(plrPos.Motion.X * 40) - 4 * weatherData.curWindSpeed.X; float dy = (float)(plrPos.Motion.Y * 40); float dz = (float)(plrPos.Motion.Z * 40); hailParticle.MinPos.Set(particlePos.X + dx, particlePos.Y + 15 + dy, particlePos.Z + dz); hailParticle.MinSize = 0.3f * (0.5f + conds.Rainfall); // * weatherData.PrecParticleSize; hailParticle.MaxSize = 1f * (0.5f + conds.Rainfall); // * weatherData.PrecParticleSize; //hailParticle.AddPos.Set(80, 5, 80); hailParticle.Color = ColorUtil.ToRgba(220, 210, 230, 255); hailParticle.MinQuantity = 100 * plevel; hailParticle.AddQuantity = 25 * plevel; hailParticle.MinVelocity.Set(-0.025f + 7.5f * weatherData.curWindSpeed.X, -5f, -0.025f); hailParticle.AddVelocity.Set(0.05f + 7.5f * weatherData.curWindSpeed.X, 0.05f, 0.05f); manager.Spawn(hailParticle); return(true); } if (precType == EnumPrecipitationType.Rain) { float dx = (float)(plrPos.Motion.X * 80); float dy = (float)(plrPos.Motion.Y * 80); float dz = (float)(plrPos.Motion.Z * 80); rainParticle.MinPos.Set(particlePos.X - 30 + dx, particlePos.Y + 15 + dy, particlePos.Z - 30 + dz); rainParticle.WithTerrainCollision = false; rainParticle.MinQuantity = 1000 * plevel; rainParticle.LifeLength = 1f; rainParticle.AddQuantity = 25 * plevel; rainParticle.MinSize = 0.15f * (0.5f + conds.Rainfall); // * weatherData.PrecParticleSize; rainParticle.MaxSize = 0.22f * (0.5f + conds.Rainfall); // weatherData.PrecParticleSize; rainParticle.Color = rainParticleColor; rainParticle.MinVelocity.Set(-0.025f + 8 * weatherData.curWindSpeed.X, -10f, -0.025f); rainParticle.AddVelocity.Set(0.05f + 8 * weatherData.curWindSpeed.X, 0.05f, 0.05f); manager.Spawn(rainParticle); splashParticles.MinVelocity = new Vec3f(-1f, 3, -1f); splashParticles.AddVelocity = new Vec3f(2, 0, 2); splashParticles.LifeLength = 0.1f; splashParticles.MinSize = 0.07f * (0.5f + 0.65f * conds.Rainfall); // weatherData.PrecParticleSize; splashParticles.MaxSize = 0.2f * (0.5f + 0.65f * conds.Rainfall); // weatherData.PrecParticleSize; splashParticles.ShouldSwimOnLiquid = true; splashParticles.Color = rainParticleColor; float cnt = 100 * plevel; for (int i = 0; i < cnt; i++) { double px = particlePos.X + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); double pz = particlePos.Z + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); int py = capi.World.BlockAccessor.GetRainMapHeightAt((int)px, (int)pz); Block block = capi.World.BlockAccessor.GetBlock((int)px, py, (int)pz); if (block.IsLiquid()) { splashParticles.MinPos.Set(px, py + block.TopMiddlePos.Y - 1 / 8f, pz); splashParticles.AddVelocity.Y = 1.5f; splashParticles.LifeLength = 0.17f; splashParticles.Color = onwaterSplashParticleColor; } else { double b = 0.75 + 0.25 * rand.NextDouble(); int ca = 230 - rand.Next(100); int cr = (int)(((rainParticleColor >> 16) & 0xff) * b); int cg = (int)(((rainParticleColor >> 8) & 0xff) * b); int cb = (int)(((rainParticleColor >> 0) & 0xff) * b); splashParticles.Color = (ca << 24) | (cr << 16) | (cg << 8) | cb; splashParticles.AddVelocity.Y = 0f; splashParticles.LifeLength = 0.1f; splashParticles.MinPos.Set(px, py + block.TopMiddlePos.Y + 0.05, pz); } manager.Spawn(splashParticles); } } if (precType == EnumPrecipitationType.Snow) { float wetness = 2.5f * GameMath.Clamp(ws.clientClimateCond.Temperature + 1, 0, 4) / 4f; float dx = (float)(plrPos.Motion.X * 40) - (30 - 9 * wetness) * weatherData.curWindSpeed.X; float dy = (float)(plrPos.Motion.Y * 40); float dz = (float)(plrPos.Motion.Z * 40); snowParticle.MinVelocity.Set(-0.5f + 5 * weatherData.curWindSpeed.X, -1f, -0.5f); snowParticle.AddVelocity.Set(1f + 5 * weatherData.curWindSpeed.X, 0.05f, 1f); snowParticle.Color = ColorUtil.ToRgba(255, 255, 255, 255); snowParticle.MinQuantity = 90 * plevel * (1 + wetness / 3); snowParticle.AddQuantity = 15 * plevel * (1 + wetness / 3); snowParticle.ParentVelocity = parentVeloSnow; snowParticle.ShouldDieInLiquid = true; snowParticle.LifeLength = Math.Max(1f, 4f - wetness); snowParticle.Color = ColorUtil.ColorOverlay(ColorUtil.ToRgba(255, 255, 255, 255), rainParticle.Color, wetness / 4f); snowParticle.GravityEffect = 0.005f * (1 + 20 * wetness); snowParticle.MinSize = 0.1f * conds.Rainfall; // weatherData.PrecParticleSize; snowParticle.MaxSize = 0.3f * conds.Rainfall / (1 + wetness); // weatherData.PrecParticleSize / (1 + wetness); float hrange = 40; float vrange = 20; snowParticle.MinPos.Set(particlePos.X - hrange + dx, particlePos.Y + vrange + dy, particlePos.Z - hrange + dz); snowParticle.AddPos.Set(2 * hrange + dx, -0.66f * vrange + dy, 2 * hrange + dz); manager.Spawn(snowParticle); } return(true); }
private bool asyncParticleSpawn(float dt, IAsyncParticleManager manager) { WeatherDataSnapshot weatherData = ws.blendedWeatherData; float plevel = weatherData.PrecIntensity * capi.Settings.Int["particleLevel"] / 100f; EnumPrecipitationType precType = weatherData.nowPrecType; particlePos.Set(capi.World.Player.Entity.Pos.X, capi.World.Player.Entity.Pos.Y, capi.World.Player.Entity.Pos.Z); EntityPos plrPos = capi.World.Player.Entity.Pos; centerPos.Set((int)particlePos.X, 0, (int)particlePos.Z); for (int lx = 0; lx < 16; lx++) { int dx = (lx - 8) * 4; for (int lz = 0; lz < 16; lz++) { int dz = (lz - 8) * 4; lowResRainHeightMap[lx, lz] = capi.World.BlockAccessor.GetRainMapHeightAt(centerPos.X + dx, centerPos.Z + dz); } } int rainYPos = capi.World.BlockAccessor.GetRainMapHeightAt((int)particlePos.X, (int)particlePos.Z); parentVeloSnow.X = -Math.Max(0, weatherData.curWindSpeed.X / 2 - 0.15f); parentVeloSnow.Y = 0; parentVeloSnow.Z = 0; // Don't spawn if wind speed below 70% or if the player is 10 blocks above ground if (weatherData.curWindSpeed.X > 0.7f && particlePos.Y - rainYPos < 10) { float dx = (float)(plrPos.Motion.X * 40) - 50 * weatherData.curWindSpeed.X; float dy = (float)(plrPos.Motion.Y * 40); float dz = (float)(plrPos.Motion.Z * 40); dustParticles.MinPos.Set(particlePos.X - 40 + dx, particlePos.Y + 15 + dy, particlePos.Z - 40 + dz); dustParticles.AddPos.Set(80, -20, 80); dustParticles.GravityEffect = -0.1f - (float)rand.NextDouble() * 0.1f; dustParticles.ParticleModel = EnumParticleModel.Quad; dustParticles.LifeLength = 1f; dustParticles.DieOnRainHeightmap = true; dustParticles.WindAffectednes = 8f; dustParticles.MinQuantity = 0; dustParticles.AddQuantity = 6 * (weatherData.curWindSpeed.X - 0.7f); dustParticles.MinSize = 0.1f; dustParticles.MaxSize = 0.4f; dustParticles.MinVelocity.Set(-0.025f + 8 * weatherData.curWindSpeed.X, -0.2f, -0.025f); dustParticles.AddVelocity.Set(0.05f + 4 * weatherData.curWindSpeed.X, 0.05f, 0.05f); for (int i = 0; i < 6; i++) { double px = particlePos.X + dx + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); double pz = particlePos.Z + dz + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); int py = capi.World.BlockAccessor.GetRainMapHeightAt((int)px, (int)pz); Block block = capi.World.BlockAccessor.GetBlock((int)px, py, (int)pz); if (block.IsLiquid()) { continue; } tmpPos.Set((int)px, py, (int)pz); dustParticles.Color = ColorUtil.ReverseColorBytes(block.GetColor(capi, tmpPos)); dustParticles.Color |= 255 << 24; manager.Spawn(dustParticles); } } if (weatherData.PrecIntensity <= 0.02) { return(true); } if (precType == EnumPrecipitationType.Hail) { float dx = (float)(plrPos.Motion.X * 40) - 4 * weatherData.curWindSpeed.X; float dy = (float)(plrPos.Motion.Y * 40); float dz = (float)(plrPos.Motion.Z * 40); hailParticle.MinPos.Set(particlePos.X - 30 + dx, particlePos.Y + 15 + dy, particlePos.Z - 30 + dz); hailParticle.GravityEffect = 1f; hailParticle.ParticleModel = EnumParticleModel.Cube; hailParticle.LifeLength = 3f; hailParticle.MinSize = 0.3f * weatherData.PrecParticleSize; hailParticle.MaxSize = 1f * weatherData.PrecParticleSize; hailParticle.AddPos.Set(60, 5, 60); hailParticle.DieOnRainHeightmap = false; hailParticle.WithTerrainCollision = true; hailParticle.MinQuantity = 100 * plevel; hailParticle.AddQuantity = 25 * plevel; hailParticle.WindAffectednes = 0f; hailParticle.ParentVelocity = null; hailParticle.Bouncy = true; hailParticle.MinVelocity.Set(-0.025f + 7.5f * weatherData.curWindSpeed.X, -5f, -0.025f); hailParticle.AddVelocity.Set(0.05f + 7.5f * weatherData.curWindSpeed.X, 0.05f, 0.05f); manager.Spawn(hailParticle); return(true); } if (precType == EnumPrecipitationType.Rain) { float dx = (float)(plrPos.Motion.X * 80); float dy = (float)(plrPos.Motion.Y * 80); float dz = (float)(plrPos.Motion.Z * 80); rainParticle.MinPos.Set(particlePos.X - 30 + dx, particlePos.Y + 15 + dy, particlePos.Z - 30 + dz); rainParticle.WithTerrainCollision = false; rainParticle.MinQuantity = 1000 * plevel; rainParticle.LifeLength = 1f; rainParticle.AddQuantity = 25 * plevel; rainParticle.MinSize = 0.15f * weatherData.PrecParticleSize; rainParticle.MaxSize = 0.22f * weatherData.PrecParticleSize; rainParticle.MinVelocity.Set(-0.025f + 8 * weatherData.curWindSpeed.X, -10f, -0.025f); rainParticle.AddVelocity.Set(0.05f + 8 * weatherData.curWindSpeed.X, 0.05f, 0.05f); manager.Spawn(rainParticle); splashParticles.MinVelocity = new Vec3f(-1f, 3, -1f); splashParticles.AddVelocity = new Vec3f(2, 0, 2); splashParticles.LifeLength = 0.1f; splashParticles.MinSize = 0.07f * weatherData.PrecParticleSize; splashParticles.MaxSize = 0.2f * weatherData.PrecParticleSize; splashParticles.ShouldSwimOnLiquid = true; float cnt = 75 * plevel; for (int i = 0; i < cnt; i++) { double px = particlePos.X + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); double pz = particlePos.Z + (rand.NextDouble() * rand.NextDouble()) * 60 * (1 - 2 * rand.Next(2)); int py = capi.World.BlockAccessor.GetRainMapHeightAt((int)px, (int)pz); Block block = capi.World.BlockAccessor.GetBlock((int)px, py, (int)pz); if (block.IsLiquid()) { splashParticles.MinPos.Set(px, py + block.TopMiddlePos.Y - 1 / 8f, pz); splashParticles.AddVelocity.Y = 1.5f; splashParticles.LifeLength = 0.17f; } else { splashParticles.AddVelocity.Y = 0f; splashParticles.LifeLength = 0.1f; splashParticles.MinPos.Set(px, py + block.TopMiddlePos.Y + 0.05, pz); } manager.Spawn(splashParticles); } } if (precType == EnumPrecipitationType.Snow) { float wetness = 2.5f * GameMath.Clamp(ws.clientClimateCond.Temperature + 1, 0, 4) / 4f; float dx = (float)(plrPos.Motion.X * 40) - (30 - 9 * wetness) * weatherData.curWindSpeed.X; float dy = (float)(plrPos.Motion.Y * 40); float dz = (float)(plrPos.Motion.Z * 40); snowParticle.MinVelocity.Set(-0.5f + 5 * weatherData.curWindSpeed.X, -1f, -0.5f); snowParticle.AddVelocity.Set(1f + 5 * weatherData.curWindSpeed.X, 0.05f, 1f); snowParticle.Color = ColorUtil.ToRgba(255, 255, 255, 255); snowParticle.MinQuantity = 90 * plevel * (1 + wetness / 3); snowParticle.AddQuantity = 15 * plevel * (1 + wetness / 3); snowParticle.ParentVelocity = parentVeloSnow; snowParticle.ShouldDieInLiquid = true; snowParticle.LifeLength = Math.Max(1f, 4f - wetness); snowParticle.Color = ColorUtil.ColorOverlay(ColorUtil.ToRgba(255, 255, 255, 255), rainParticle.Color, wetness / 4f); snowParticle.GravityEffect = 0.005f * (1 + 20 * wetness); snowParticle.MinSize = 0.1f * weatherData.PrecParticleSize; snowParticle.MaxSize = 0.3f * weatherData.PrecParticleSize / (1 + wetness); float hrange = 40; float vrange = 20; snowParticle.MinPos.Set(particlePos.X - hrange + dx, particlePos.Y + vrange + dy, particlePos.Z - hrange + dz); snowParticle.AddPos.Set(2 * hrange + dx, -0.66f * vrange + dy, 2 * hrange + dz); manager.Spawn(snowParticle); } return(true); }