示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
                }
            }
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        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)
        {
            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 bool ShouldReceiveClientParticleTicks(IWorldAccessor world, IPlayer player, BlockPos pos, out bool isWindAffected)
        //{
        //    bool val = base.ShouldReceiveClientParticleTicks(world, player, pos, out _);
        //    isWindAffected = false;

        //    return val;
        //}

        public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking)
        {
            BlockEntityOven beo = manager.BlockAccess.GetBlockEntity(pos) as BlockEntityOven;

            if (beo != null && beo.IsBurning)
            {
                beo.RenderParticleTick(manager, pos, windAffectednessAtPos, secondsTicking, particles);
            }

            base.OnAsyncClientParticleTick(manager, pos, windAffectednessAtPos, secondsTicking);
        }
示例#9
0
        public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking)
        {
            BlockEntityBoiler be = api.World.BlockAccessor.GetBlockEntity(pos) as BlockEntityBoiler;

            if (be != null && be.firepitStage == 6)
            {
                firepitBlock.OnAsyncClientParticleTick(manager, pos, windAffectednessAtPos, secondsTicking);
                return;
            }

            base.OnAsyncClientParticleTick(manager, pos, windAffectednessAtPos, secondsTicking);
        }
示例#10
0
        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);
                }
            }
        }
示例#12
0
 //LOOK OnAsyncClientParticleTick
 public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking)
 {
     base.OnAsyncClientParticleTick(manager, pos, windAffectednessAtPos, secondsTicking);
 }
        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 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);
        }
示例#15
0
        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);
        }
示例#16
0
        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);
            }
        }
示例#17
0
        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);
        }
示例#18
0
        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);
                }
            }
        }
示例#19
0
        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);
            }
        }
示例#20
0
        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;

            float dryness = GameMath.Clamp(1 - precIntensity, 0, 1);

            tmpPos.Set((int)plrPos.X, (int)plrPos.Y, (int)plrPos.Z);

            precIntensity = Math.Max(0, precIntensity - (float)Math.Max(0, (plrPos.Y - capi.World.SeaLevel - 5000) / 10000f));


            EnumPrecipitationType precType = weatherData.BlendedPrecType;

            if (precType == EnumPrecipitationType.Auto)
            {
                precType = conds.Temperature < weatherData.snowThresholdTemp ? EnumPrecipitationType.Snow : EnumPrecipitationType.Rain;
            }

            int rainYPos = capi.World.BlockAccessor.GetRainMapHeightAt((int)particlePos.X, (int)particlePos.Z);

            particlePos.Set(capi.World.Player.Entity.Pos.X, rainYPos, capi.World.Player.Entity.Pos.Z);


            int onwaterSplashParticleColor = capi.World.ApplyColorMapOnRgba(lblock.ClimateColorMapResolved, lblock.SeasonColorMapResolved, 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);
                }
            }



            parentVeloSnow.X = -Math.Max(0, weatherData.curWindSpeed.X / 2 - 0.15f);
            parentVeloSnow.Y = 0;

            parentVeloSnow.Z = 0;

            // Don't spawn if wind speed below 50% or if the player is 10 blocks above ground
            if (weatherData.curWindSpeed.X > 0.5f) // && particlePos.Y - rainYPos < 10
            {
                SpawnDustParticles(manager, weatherData, plrPos, dryness, onwaterSplashParticleColor);
            }

            particlePos.Y = capi.World.Player.Entity.Pos.Y;

            if (precIntensity <= 0.02)
            {
                return(true);
            }

            if (precType == EnumPrecipitationType.Hail)
            {
                SpawnHailParticles(manager, weatherData, conds, plrPos, plevel);
                return(true);
            }


            if (precType == EnumPrecipitationType.Rain)
            {
                SpawnRainParticles(manager, weatherData, conds, plrPos, plevel, onwaterSplashParticleColor);
            }


            if (precType == EnumPrecipitationType.Snow)
            {
                SpawnSnowParticles(manager, weatherData, conds, plrPos, plevel);
            }

            return(true);
        }