コード例 #1
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);
        }
コード例 #2
0
        /// <summary>
        /// Get the current precipitation as seen by the client at pos
        /// </summary>
        /// <param name="rainOnly">If true, returns 0 if it is currently snowing</param>
        /// <returns></returns>
        public double GetActualRainLevel(BlockPos pos, bool rainOnly = false)
        {
            ClimateCondition conds = clientClimateCond;

            if (conds == null || !playerChunkLoaded)
            {
                return(0.0);
            }
            float precIntensity = conds.Rainfall;

            if (rainOnly)
            {
                // TODO:  Testing whether it is snowing or not on the client is kinda slow - though the WeatherSimulationParticles must already know!

                WeatherDataSnapshot   weatherData = BlendedWeatherData;
                EnumPrecipitationType precType    = weatherData.BlendedPrecType;
                if (precType == EnumPrecipitationType.Auto)
                {
                    precType = conds.Temperature < weatherData.snowThresholdTemp ? EnumPrecipitationType.Snow : EnumPrecipitationType.Rain;
                }
                if (precType == EnumPrecipitationType.Snow)
                {
                    return(0d);
                }
            }

            return(precIntensity);
        }
コード例 #3
0
        /// <summary>
        /// Get the current precipitation as seen by the client at pos
        /// </summary>
        /// <param name="rainOnly">If true, returns 0 if it is currently snowing</param>
        /// <returns></returns>
        public double GetActualRainLevel(BlockPos pos, bool rainOnly = false)
        {
            ClimateCondition conds = clientClimateCond;

            if (conds == null || !playerChunkLoaded)
            {
                return(0.0);
            }
            float precIntensity = conds.Rainfall;

            if (rainOnly)
            {
                WeatherDataSnapshot   weatherData = BlendedWeatherData;
                EnumPrecipitationType precType    = weatherData.BlendedPrecType;
                if (precType == EnumPrecipitationType.Auto)
                {
                    precType = conds.Temperature < weatherData.snowThresholdTemp ? EnumPrecipitationType.Snow : EnumPrecipitationType.Rain;
                }
                if (precType == EnumPrecipitationType.Snow)
                {
                    return(0d);
                }
            }

            return(precIntensity);
        }
コード例 #4
0
        private void desertStormSim(float dt)
        {
            accum += dt;

            if (accum > 2)
            {
                int   cnt        = spawnCount;
                int   sum        = sandFinds;
                int[] sandBlocks = sandCountByBlock;

                if (cnt > 10 && sum > 0)
                {
                    sandCountByBlock = new int[indicesBySandBlockId.Count];
                    spawnCount       = 0;
                    sandFinds        = 0;

                    WeatherDataSnapshot weatherData = ws.BlendedWeatherData;
                    var climate = capi.World.BlockAccessor.GetClimateAt(capi.World.Player.Entity.Pos.AsBlockPos, EnumGetClimateMode.NowValues);

                    float climateWeight = 2f * Math.Max(0, weatherData.curWindSpeed.X - 0.5f) * (1 - climate.WorldgenRainfall) * (1 - climate.Rainfall);

                    var pos = capi.World.Player.Entity.Pos.AsBlockPos;
                    targetFogColor[0] = targetFogColor[1] = targetFogColor[2] = 0;
                    foreach (var val in indicesBySandBlockId)
                    {
                        int   blockCount = sandBlocks[val.Value];
                        float weight     = (float)blockCount / sum;

                        int      col      = capi.World.GetBlock(val.Key).GetColor(capi, pos);
                        double[] colparts = ColorUtil.ToRGBADoubles(col);

                        targetFogColor[0] += (float)colparts[2] * weight;
                        targetFogColor[1] += (float)colparts[1] * weight;
                        targetFogColor[2] += (float)colparts[0] * weight;
                    }

                    float sandRatio = (float)(sum / 30.0 / cnt) * climateWeight;
                    targetFogDensity = sandRatio;
                }

                accum = 0;
            }

            float dtf = dt / 3f;

            desertStormAmbient.FogColor.Value[0] += (targetFogColor[0] - desertStormAmbient.FogColor.Value[0]) * dtf;
            desertStormAmbient.FogColor.Value[1] += (targetFogColor[1] - desertStormAmbient.FogColor.Value[1]) * dtf;
            desertStormAmbient.FogColor.Value[2] += (targetFogColor[2] - desertStormAmbient.FogColor.Value[2]) * dtf;

            desertStormAmbient.FogDensity.Value  += ((float)Math.Pow(targetFogDensity, 1.2f) - desertStormAmbient.FogDensity.Value) * dtf;
            desertStormAmbient.FogDensity.Weight += (targetFogDensity - desertStormAmbient.FogDensity.Weight) * dtf;
            desertStormAmbient.FogColor.Weight   += (Math.Min(1, 2 * targetFogDensity) - desertStormAmbient.FogColor.Weight) * dtf;
        }
コード例 #5
0
        public void BiLerp(WeatherDataSnapshot topLeft, WeatherDataSnapshot topRight, WeatherDataSnapshot botLeft, WeatherDataSnapshot botRight, float lerpleftRight, float lerptopBot)
        {
            WeatherDataSnapshot top = new WeatherDataSnapshot();

            top.SetLerped(topLeft, topRight, lerpleftRight);

            WeatherDataSnapshot bot = new WeatherDataSnapshot();

            bot.SetLerped(botLeft, botRight, lerptopBot);

            SetLerped(top, bot, lerptopBot);
        }
コード例 #6
0
        public void ClientTick(float dt)
        {
            Random rnd = capi.World.Rand;
            WeatherDataSnapshot weatherData = weatherSys.BlendedWeatherData;

            if (weatherSys.clientClimateCond.Temperature >= weatherData.lightningMinTemp)
            {
                float deepnessSub = GameMath.Clamp(1 - (float)capi.World.Player.Entity.Pos.Y / capi.World.SeaLevel, 0, 1);

                double rndval = capi.World.Rand.NextDouble();
                rndval -= weatherData.distantLightningRate * weatherSys.clientClimateCond.RainCloudOverlay;
                if (rndval <= 0)
                {
                    lightningTime      = 0.07f + (float)rnd.NextDouble() * 0.17f;
                    lightningIntensity = 0.25f + (float)rnd.NextDouble();



                    float pitch  = GameMath.Clamp((float)rnd.NextDouble() * 0.3f + lightningTime / 2 + lightningIntensity / 2 - deepnessSub / 2, 0.6f, 1.15f);
                    float volume = GameMath.Clamp(Math.Min(1, 0.25f + lightningTime + lightningIntensity / 2) - 2f * deepnessSub, 0, 1);

                    capi.World.PlaySoundAt(new AssetLocation("sounds/weather/lightning-distant.ogg"), 0, 0, 0, null, EnumSoundType.Weather, pitch, 32, volume);
                }
                else if (nearLightningCoolDown <= 0)
                {
                    rndval -= weatherData.nearLightningRate * weatherSys.clientClimateCond.RainCloudOverlay;
                    if (rndval <= 0)
                    {
                        lightningTime      = 0.07f + (float)rnd.NextDouble() * 0.17f;
                        lightningIntensity = 1 + (float)rnd.NextDouble() * 0.9f;

                        float         pitch  = GameMath.Clamp(0.75f + (float)rnd.NextDouble() * 0.3f - deepnessSub / 2, 0.5f, 1.2f);
                        float         volume = GameMath.Clamp(0.5f + (float)rnd.NextDouble() * 0.5f - 2f * deepnessSub, 0, 1);
                        AssetLocation loc;

                        if (rnd.NextDouble() > 0.25)
                        {
                            loc = new AssetLocation("sounds/weather/lightning-near.ogg");
                            nearLightningCoolDown = 5;
                        }
                        else
                        {
                            loc = new AssetLocation("sounds/weather/lightning-verynear.ogg");
                            nearLightningCoolDown = 10;
                        }


                        capi.World.PlaySoundAt(loc, 0, 0, 0, null, EnumSoundType.Weather, pitch, 32, volume);
                    }
                }
            }
        }
コード例 #7
0
        public void SetLerped(WeatherDataSnapshot left, WeatherDataSnapshot right, float w)
        {
            Ambient.SetLerped(left.Ambient, right.Ambient, w);
            PrecIntensity    = left.PrecIntensity * (1 - w) + right.PrecIntensity * w;
            PrecParticleSize = left.PrecParticleSize * (1 - w) + right.PrecParticleSize * w;

            nowPrecType          = w < 0.5 ? left.nowPrecType : right.nowPrecType;
            BlendedPrecType      = w < 0.5 ? left.BlendedPrecType : right.BlendedPrecType;
            nearLightningRate    = left.nearLightningRate * (1 - w) + right.nearLightningRate * w;
            distantLightningRate = left.distantLightningRate * (1 - w) + right.distantLightningRate * w;
            lightningMinTemp     = left.lightningMinTemp * (1 - w) + right.lightningMinTemp * w;
            climateCond.SetLerped(left.climateCond, right.climateCond, w);
            curWindSpeed.X    = left.curWindSpeed.X * (1 - w) + right.curWindSpeed.X * w;
            snowThresholdTemp = left.snowThresholdTemp * (1 - w) + right.snowThresholdTemp * w;
        }
コード例 #8
0
        public void ClientTick(float dt)
        {
            Random rnd = capi.World.Rand;
            WeatherDataSnapshot weatherData = weatherSys.blendedWeatherData;

            if (weatherSys.clientClimateCond.Temperature >= weatherData.lightningMinTemp && weatherData.nowPrecType == EnumPrecipitationType.Rain)
            {
                double rndval = capi.World.Rand.NextDouble();
                rndval -= weatherData.distantLightningRate;
                if (rndval <= 0)
                {
                    lightningTime      = 0.07f + (float)rnd.NextDouble() * 0.17f;
                    lightningIntensity = 0.25f + (float)rnd.NextDouble();

                    float pitch  = GameMath.Clamp((float)rnd.NextDouble() * 0.3f + lightningTime / 2 + lightningIntensity / 2, 0.6f, 1.15f);
                    float volume = Math.Min(1, 0.25f + lightningTime + lightningIntensity / 2);

                    capi.World.PlaySoundAt(new AssetLocation("sounds/weather/lightning-distant.ogg"), 0, 0, 0, null, pitch, 32, volume);
                }
                else if (nearLightningCoolDown <= 0)
                {
                    rndval -= weatherData.nearLightningRate;
                    if (rndval <= 0)
                    {
                        lightningTime      = 0.07f + (float)rnd.NextDouble() * 0.17f;
                        lightningIntensity = 1 + (float)rnd.NextDouble() * 0.9f;

                        float         pitch  = 0.75f + (float)rnd.NextDouble() * 0.3f;
                        float         volume = 0.5f + (float)rnd.NextDouble() * 0.5f;
                        AssetLocation loc;

                        if (rnd.NextDouble() > 0.25)
                        {
                            loc = new AssetLocation("sounds/weather/lightning-near.ogg");
                            nearLightningCoolDown = 5;
                        }
                        else
                        {
                            loc = new AssetLocation("sounds/weather/lightning-verynear.ogg");
                            nearLightningCoolDown = 10;
                        }


                        capi.World.PlaySoundAt(loc, 0, 0, 0, null, pitch, 32, volume);
                    }
                }
            }
        }
コード例 #9
0
        public void InitDummySim()
        {
            dummySim         = new WeatherSimulationRegion(this, 0, 0);
            dummySim.IsDummy = true;
            dummySim.Initialize();

            var rand = new LCGRandom(api.World.Seed);

            rand.InitPositionSeed(3, 3);

            rainOverlayPattern = new WeatherPattern(this, GeneralConfig.RainOverlayPattern, rand, 0, 0);
            rainOverlayPattern.Initialize(0, api.World.Seed);
            rainOverlayPattern.OnBeginUse();

            rainOverlaySnap = new WeatherDataSnapshot();
        }
コード例 #10
0
        public void LoadLerp(Vec3d pos, bool useArgValues, float lerpRainCloudOverlay = 0, float lerpRainOverlay = 0, float dt = 1)
        {
            int regSize = api.World.BlockAccessor.RegionSize;

            double regionRelX = (pos.X / regSize) - (int)Math.Round(pos.X / regSize);
            double regionRelZ = (pos.Z / regSize) - (int)Math.Round(pos.Z / regSize);

            LerpTopBot    = GameMath.Smootherstep(regionRelX + 0.5);
            LerpLeftRight = GameMath.Smootherstep(regionRelZ + 0.5);

            rainOverlayData = ws.rainOverlayPattern;
            rainSnapData    = ws.rainOverlaySnap;


            if (hereMapRegion == null)
            {
                this.lerpRainCloudOverlay = 0;
                this.lerpRainOverlay      = 0;
            }
            else
            {
                if (useArgValues)
                {
                    this.lerpRainCloudOverlay = lerpRainCloudOverlay;
                    this.lerpRainOverlay      = lerpRainOverlay;
                }
                else
                {
                    tmpPos.Set((int)pos.X, (int)pos.Y, (int)pos.Z);

                    int noiseSizeClimate = hereMapRegion.ClimateMap.InnerSize;
                    int climate          = 128 | (128 << 8) | (128 << 16);

                    if (noiseSizeClimate > 0)
                    {
                        double posXInRegionClimate = Math.Max(0, (pos.X / regSize - (int)pos.X / regSize) * noiseSizeClimate);
                        double posZInRegionClimate = Math.Max(0, (pos.Z / regSize - (int)pos.Z / regSize) * noiseSizeClimate);
                        climate = hereMapRegion.ClimateMap.GetUnpaddedColorLerped((float)posXInRegionClimate, (float)posZInRegionClimate);
                    }

                    ClimateCondition conds  = ws.GetClimateFast(tmpPos, climate);
                    float            tspeed = Math.Min(1, dt * 10);
                    this.lerpRainCloudOverlay = this.lerpRainCloudOverlay + (conds.RainCloudOverlay - this.lerpRainCloudOverlay) * tspeed;
                    this.lerpRainOverlay      = this.lerpRainOverlay + (conds.Rainfall - this.lerpRainOverlay) * tspeed;
                }
            }
        }
コード例 #11
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);
        }
コード例 #12
0
        public void OnRenderFrame(float dt, EnumRenderStage stage)
        {
            if (stage == EnumRenderStage.Done)
            {
                AmbientModifier sunGlowAmb = capi.Ambient.CurrentModifiers["sunglow"];
                actualSunGlowAmb.FogColor.Weight = sunGlowAmb.FogColor.Weight;
                //actualSunGlowAmb.AmbientColor.Weight = sunGlowAmb.AmbientColor.Weight;

                dt = Math.Min(0.5f, dt);

                if (nearLightningCoolDown > 0)
                {
                    nearLightningCoolDown -= dt;
                }

                return;
            }

            if (lightningTime > 0)
            {
                float mul = Math.Min(10 * lightningIntensity * lightningTime, 1.5f);

                WeatherDataSnapshot weatherData = weatherSys.BlendedWeatherData;

                LightningAmbient.CloudBrightness.Value = Math.Max(weatherData.Ambient.SceneBrightness.Value, mul);
                LightningAmbient.FogBrightness.Value   = Math.Max(weatherData.Ambient.FogBrightness.Value, mul);

                LightningAmbient.CloudBrightness.Weight = Math.Min(1, mul);
                LightningAmbient.FogBrightness.Weight   = Math.Min(1, mul);

                float sceneBrightIncrease = GameMath.Min(mul, GameMath.Max(0, lightningIntensity - 0.75f));

                if (sceneBrightIncrease > 0)
                {
                    LightningAmbient.SceneBrightness.Weight = Math.Min(1, sceneBrightIncrease);
                    LightningAmbient.SceneBrightness.Value  = 1;

                    AmbientModifier sunGlowAmb = capi.Ambient.CurrentModifiers["sunglow"];

                    float nowWeight = GameMath.Clamp(1 - sceneBrightIncrease, 0, 1);

                    sunGlowAmb.FogColor.Weight     = Math.Min(sunGlowAmb.FogColor.Weight, nowWeight);
                    sunGlowAmb.AmbientColor.Weight = Math.Min(sunGlowAmb.AmbientColor.Weight, nowWeight);
                }


                lightningTime -= dt / 1.7f;

                if (lightningTime <= 0)
                {
                    // Restore previous values
                    AmbientModifier sunGlowAmb = capi.Ambient.CurrentModifiers["sunglow"];
                    sunGlowAmb.FogColor.Weight     = actualSunGlowAmb.FogColor.Weight;
                    sunGlowAmb.AmbientColor.Weight = actualSunGlowAmb.AmbientColor.Weight;

                    LightningAmbient.CloudBrightness.Weight = 0;
                    LightningAmbient.FogBrightness.Weight   = 0;
                    LightningAmbient.SceneBrightness.Weight = 0;
                }
            }
        }
コード例 #13
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);
            }
        }
コード例 #14
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);
                }
            }
        }
コード例 #15
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);
        }
コード例 #16
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;

            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);
        }
コード例 #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 updateSounds(float dt)
        {
            float targetRainVolumeLeafy    = 0;
            float targetRainVolumeLeafless = 0;
            float targetHailVolume         = 0;
            float targetTrembleVolume      = 0;

            float targetRainPitch = 1;
            float targetHailPitch = 1;

            WeatherDataSnapshot weatherData = weatherSys.BlendedWeatherData;

            if (searchComplete)
            {
                EntityPlayer eplr = capi.World.Player.Entity;
                plrPos.Set((int)eplr.Pos.X, (int)eplr.Pos.Y, (int)eplr.Pos.Z);
                searchComplete = false;

                TyronThreadPool.QueueTask(() =>
                {
                    float val           = (float)Math.Pow(Math.Max(0, (capi.World.BlockAccessor.GetDistanceToRainFall(plrPos, 12, 4) - 2) / 10f), 2);
                    roomVolumePitchLoss = GameMath.Clamp(val, 0, 1);
                    searchComplete      = true;
                });
            }

            EnumPrecipitationType precType = weatherData.BlendedPrecType;

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

            float nearbyLeaviness = GameMath.Clamp(GlobalConstants.CurrentNearbyRelLeavesCountClient * 60, 0, 1);

            ClimateCondition conds = weatherSys.clientClimateCond;

            if (conds.Rainfall > 0)
            {
                if (precType == EnumPrecipitationType.Rain || weatherSys.clientClimateCond.Temperature < weatherData.snowThresholdTemp)
                {
                    targetRainVolumeLeafy = nearbyLeaviness * GameMath.Clamp(conds.Rainfall * 2f - Math.Max(0, 2f * (weatherData.snowThresholdTemp - weatherSys.clientClimateCond.Temperature)), 0, 1);
                    targetRainVolumeLeafy = GameMath.Max(0, targetRainVolumeLeafy - roomVolumePitchLoss);

                    targetRainVolumeLeafless = Math.Max(0.3f, 1 - nearbyLeaviness) * GameMath.Clamp(conds.Rainfall * 2f - Math.Max(0, 2f * (weatherData.snowThresholdTemp - weatherSys.clientClimateCond.Temperature)), 0, 1);
                    targetRainVolumeLeafless = GameMath.Max(0, targetRainVolumeLeafless - roomVolumePitchLoss);

                    targetRainPitch = Math.Max(0.7f, 1.25f - conds.Rainfall * 0.7f);
                    targetRainPitch = Math.Max(0, targetRainPitch - roomVolumePitchLoss / 4f);

                    targetTrembleVolume = GameMath.Clamp(conds.Rainfall * 1.6f - 0.8f - roomVolumePitchLoss * 0.25f, 0, 1);

                    if (!rainSoundsOn && (targetRainVolumeLeafy > 0.01 || targetRainVolumeLeafless > 0.01))
                    {
                        for (int i = 0; i < rainSoundsLeafless.Length; i++)
                        {
                            rainSoundsLeafless[i]?.Start();
                        }
                        for (int i = 0; i < rainSoundsLeafy.Length; i++)
                        {
                            rainSoundsLeafy[i]?.Start();
                        }

                        lowTrembleSound?.Start();
                        rainSoundsOn = true;

                        curRainPitch = targetRainPitch;
                    }

                    if (capi.World.Player.Entity.IsEyesSubmerged())
                    {
                        curRainPitch              = targetRainPitch / 2;
                        targetRainVolumeLeafy    *= 0.75f;
                        targetRainVolumeLeafless *= 0.75f;
                    }
                }

                if (precType == EnumPrecipitationType.Hail)
                {
                    targetHailVolume = GameMath.Clamp(conds.Rainfall * 2f - roomVolumePitchLoss, 0, 1);
                    targetHailVolume = GameMath.Max(0, targetHailVolume - roomVolumePitchLoss);

                    targetHailPitch = Math.Max(0.7f, 1.25f - conds.Rainfall * 0.7f);
                    targetHailPitch = Math.Max(0, targetHailPitch - roomVolumePitchLoss / 4f);

                    if (!hailSoundsOn && targetHailVolume > 0.01)
                    {
                        hailSound?.Start();
                        hailSoundsOn = true;
                        curHailPitch = targetHailPitch;
                    }
                }
            }


            curRainVolumeLeafy    += (targetRainVolumeLeafy - curRainVolumeLeafy) * dt / 2;
            curRainVolumeLeafless += (targetRainVolumeLeafless - curRainVolumeLeafless) * dt / 2;

            curTrembleVolume += (targetTrembleVolume - curTrembleVolume) * dt;
            curHailVolume    += (targetHailVolume - curHailVolume) * dt;

            curHailPitch += (targetHailPitch - curHailPitch) * dt;
            curRainPitch += (targetRainPitch - curRainPitch) * dt;



            if (rainSoundsOn)
            {
                for (int i = 0; i < rainSoundsLeafless.Length; i++)
                {
                    rainSoundsLeafless[i]?.SetVolume(curRainVolumeLeafless);
                    rainSoundsLeafless[i]?.SetPitch(curRainPitch);
                }
                for (int i = 0; i < rainSoundsLeafy.Length; i++)
                {
                    rainSoundsLeafy[i]?.SetVolume(curRainVolumeLeafy);
                    rainSoundsLeafy[i]?.SetPitch(curRainPitch);
                }

                lowTrembleSound?.SetVolume(curTrembleVolume);
            }
            if (hailSoundsOn)
            {
                hailSound?.SetVolume(curHailVolume);
                hailSound?.SetPitch(curHailPitch);
            }


            if (curRainVolumeLeafless < 0.01 && curRainVolumeLeafy < 0.01)
            {
                for (int i = 0; i < rainSoundsLeafless.Length; i++)
                {
                    rainSoundsLeafless[i]?.Stop();
                }
                for (int i = 0; i < rainSoundsLeafy.Length; i++)
                {
                    rainSoundsLeafy[i]?.Stop();
                }
                rainSoundsOn = false;
            }

            if (curHailVolume < 0.01)
            {
                hailSound?.Stop();
                hailSoundsOn = false;
            }



            float wstr = (1 - roomVolumePitchLoss) * weatherData.curWindSpeed.X - 0.3f;

            if (wstr > 0.03f || curWindVolumeLeafy > 0.01f || curWindVolumeLeafless > 0.01f)
            {
                if (!windSoundsOn)
                {
                    windSoundLeafy?.Start();
                    windSoundLeafless?.Start();
                    windSoundsOn = true;
                }

                float targetVolumeLeafy    = nearbyLeaviness * 1.2f * wstr;
                float targetVolumeLeafless = (1 - nearbyLeaviness) * 1.2f * wstr;

                curWindVolumeLeafy    += (targetVolumeLeafy - curWindVolumeLeafy) * dt;
                curWindVolumeLeafless += (targetVolumeLeafless - curWindVolumeLeafless) * dt;

                windSoundLeafy?.SetVolume(curWindVolumeLeafy);
                windSoundLeafless?.SetVolume(curWindVolumeLeafless);
            }
            else
            {
                if (windSoundsOn)
                {
                    windSoundLeafy?.Stop();
                    windSoundLeafless?.Stop();
                    windSoundsOn = false;
                }
            }
        }
コード例 #19
0
        private string getWeatherInfo <T>(IPlayer player) where T : WeatherSystemBase
        {
            T wsys = api.ModLoader.GetModSystem <T>();

            Vec3d    plrPos = player.Entity.LocalPos.XYZ;
            BlockPos pos    = plrPos.AsBlockPos;

            wsys.LoadAdjacentSimsAndLerpValues(plrPos);

            int regionX = (int)pos.X / api.World.BlockAccessor.RegionSize;
            int regionZ = (int)pos.Z / api.World.BlockAccessor.RegionSize;

            WeatherSimulationRegion weatherSim;
            long index2d = wsys.MapRegionIndex2D(regionX, regionZ);

            wsys.weatherSimByMapRegion.TryGetValue(index2d, out weatherSim);
            if (weatherSim == null)
            {
                return("weatherSim is null. No idea what to do here");
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine(string.Format("Weather by region:")); // (lerp-lr: {0}, lerp-bt: {1}), wsys.lerpLeftRight.ToString("0.##"), wsys.lerpTopBot.ToString("0.##")));
            string[] cornerNames = new string[] { "tl", "tr", "bl", "br" };

            //topBlendedWeatherData.SetLerped(adjacentSims[0].weatherData, adjacentSims[1].weatherData, (float)lerpLeftRight);
            //botBlendedWeatherData.SetLerped(adjacentSims[2].weatherData, adjacentSims[3].weatherData, (float)lerpLeftRight);
            //blendedWeatherData.SetLerped(topBlendedWeatherData, botBlendedWeatherData, (float)lerpTopBot);

            double tlLerp = GameMath.BiLerp(1, 0, 0, 0, wsys.lerpLeftRight, wsys.lerpTopBot);
            double trLerp = GameMath.BiLerp(0, 1, 0, 0, wsys.lerpLeftRight, wsys.lerpTopBot);
            double blLerp = GameMath.BiLerp(0, 0, 1, 0, wsys.lerpLeftRight, wsys.lerpTopBot);
            double brLerp = GameMath.BiLerp(0, 0, 0, 1, wsys.lerpLeftRight, wsys.lerpTopBot);

            int[] lerps = new int[] { (int)(100 * tlLerp), (int)(100 * trLerp), (int)(100 * blLerp), (int)(100 * brLerp) };

            for (int i = 0; i < 4; i++)
            {
                WeatherSimulationRegion sim = wsys.adjacentSims[i];

                if (sim == wsys.dummySim)
                {
                    sb.AppendLine(string.Format("{0}: missing", cornerNames[i]));
                }
                else
                {
                    sb.AppendLine(string.Format("{10}% of {0}@{8}/{9}: {1}% {2}, {3}% {4}. Prec: {5}, Wind: {6} (v={7})",
                                                cornerNames[i], (int)(100 * sim.Weight), sim.NewWePattern.GetWeatherName(), (int)(100 - 100 * sim.Weight),
                                                sim.OldWePattern.GetWeatherName(), sim.weatherData.PrecIntensity.ToString("0.###"),
                                                sim.CurWindPattern.GetWindName(), sim.GetWindSpeed(pos.Y).ToString("0.###"),
                                                sim.regionX, sim.regionZ,
                                                lerps[i]
                                                ));
                }
            }

            wsys.updateAdjacentAndBlendWeatherData();

            WeatherDataSnapshot wData = wsys.blendedWeatherData;

            sb.AppendLine(string.Format(string.Format("Blended:\nPrecipitation: {0}, Particle size: {1}, Type: {2}, Wind speed: {3}", wData.PrecIntensity, wData.PrecParticleSize, wData.BlendedPrecType, wsys.GetWindSpeed(plrPos))));
            return(sb.ToString());
        }
コード例 #20
0
        public void OnRenderFrame(float dt, EnumRenderStage stage)
        {
            if (stage == EnumRenderStage.Opaque)
            {
                prog.Use();
                prog.UniformMatrix("projection", capi.Render.CurrentProjectionMatrix);
                prog.UniformMatrix("view", capi.Render.CameraMatrixOriginf);

                for (int i = 0; i < lightningFlashes.Count; i++)
                {
                    var lflash = lightningFlashes[i];
                    lflash.Render(dt);

                    if (!lflash.Alive)
                    {
                        lflash.Dispose();
                        lightningFlashes.RemoveAt(i);
                        i--;
                    }
                }

                prog.Stop();
                return;
            }

            if (stage == EnumRenderStage.Done)
            {
                AmbientModifier sunGlowAmb = capi.Ambient.CurrentModifiers["sunglow"];
                actualSunGlowAmb.FogColor.Weight = sunGlowAmb.FogColor.Weight;

                dt = Math.Min(0.5f, dt);

                if (nearLightningCoolDown > 0)
                {
                    nearLightningCoolDown -= dt;
                }

                return;
            }

            if (lightningTime > 0)
            {
                float mul = Math.Min(10 * lightningIntensity * lightningTime, 1.5f);

                WeatherDataSnapshot weatherData = weatherSysc.BlendedWeatherData;

                LightningAmbient.CloudBrightness.Value = Math.Max(weatherData.Ambient.SceneBrightness.Value, mul);
                LightningAmbient.FogBrightness.Value   = Math.Max(weatherData.Ambient.FogBrightness.Value, mul);

                LightningAmbient.CloudBrightness.Weight = Math.Min(1, mul);
                LightningAmbient.FogBrightness.Weight   = Math.Min(1, mul);

                float sceneBrightIncrease = GameMath.Min(mul, GameMath.Max(0, lightningIntensity - 0.75f));

                if (sceneBrightIncrease > 0)
                {
                    LightningAmbient.SceneBrightness.Weight = Math.Min(1, sceneBrightIncrease);
                    LightningAmbient.SceneBrightness.Value  = 1;

                    AmbientModifier sunGlowAmb = capi.Ambient.CurrentModifiers["sunglow"];

                    float nowWeight = GameMath.Clamp(1 - sceneBrightIncrease, 0, 1);

                    sunGlowAmb.FogColor.Weight     = Math.Min(sunGlowAmb.FogColor.Weight, nowWeight);
                    sunGlowAmb.AmbientColor.Weight = Math.Min(sunGlowAmb.AmbientColor.Weight, nowWeight);
                }


                lightningTime -= dt / 1.7f;

                if (lightningTime <= 0)
                {
                    // Restore previous values
                    AmbientModifier sunGlowAmb = capi.Ambient.CurrentModifiers["sunglow"];
                    sunGlowAmb.FogColor.Weight     = actualSunGlowAmb.FogColor.Weight;
                    sunGlowAmb.AmbientColor.Weight = actualSunGlowAmb.AmbientColor.Weight;

                    LightningAmbient.CloudBrightness.Weight = 0;
                    LightningAmbient.FogBrightness.Weight   = 0;
                    LightningAmbient.SceneBrightness.Weight = 0;
                }
            }
        }