Beispiel #1
0
        public override void CheckTransition(float dt)
        {
            tmpPos.Set(Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5);
            double rainLevel = 0;
            bool   rainCheck =
                Api.Side == EnumAppSide.Server &&
                Api.World.Rand.NextDouble() < 0.15 &&
                Api.World.BlockAccessor.GetRainMapHeightAt(Pos.X, Pos.Z) <= Pos.Y &&
                (rainLevel = wsys.GetPrecipitation(tmpPos)) > 0.04
            ;

            if (rainCheck && Api.World.Rand.NextDouble() < rainLevel * 5)
            {
                Api.World.PlaySoundAt(new AssetLocation("sounds/effect/extinguish"), Pos.X + 0.5, Pos.Y + 0.75, Pos.Z + 0.5, null, false, 16);
                if (Api.World.Rand.NextDouble() < 0.2 + rainLevel / 2f)
                {
                    Block block = Api.World.BlockAccessor.GetBlock(Pos);
                    if (block.Attributes == null)
                    {
                        return;
                    }
                    var toCode = block.CodeWithVariant("state", "extinct").ToShortString();
                    tryTransition(toCode);
                }
            }

            if (Api.World.Rand.NextDouble() < 0.3)
            {
                base.CheckTransition(dt);
            }
        }
        private void OnSlowServerTick(float dt)
        {
            if (!canBurn(FuelPos))
            {
                KillFire(false);
                return;
            }

            Entity[] entities = Api.World.GetEntitiesAround(FirePos.ToVec3d().Add(0.5, 0.5, 0.5), 3, 3, (e) => true);
            Vec3d    ownPos   = FirePos.ToVec3d();

            for (int i = 0; i < entities.Length; i++)
            {
                Entity entity = entities[i];
                if (!CollisionTester.AabbIntersect(entity.SelectionBox, entity.ServerPos.X, entity.ServerPos.Y, entity.ServerPos.Z, fireCuboid, ownPos))
                {
                    continue;
                }

                if (entity.Alive)
                {
                    entity.ReceiveDamage(new DamageSource()
                    {
                        Source = EnumDamageSource.Block, SourceBlock = fireBlock, SourcePos = ownPos, Type = EnumDamageType.Fire
                    }, 2f);
                }

                if (Api.World.Rand.NextDouble() < 0.125)
                {
                    entity.Ignite();
                }
            }

            if (FuelPos != FirePos && Api.World.BlockAccessor.GetBlock(FirePos).LiquidCode == "water")
            {
                KillFire(false);
                return;
            }

            if (Api.World.BlockAccessor.GetRainMapHeightAt(FirePos.X, FirePos.Z) <= FirePos.Y)   // It's more efficient to do this quick check before GetPrecipitation
            {
                // Die on rainfall
                tmpPos.Set(FirePos.X + 0.5, FirePos.Y + 0.5, FirePos.Z + 0.5);
                double rain = wsys.GetPrecipitation(tmpPos);
                if (rain > 0.15)
                {
                    Api.World.PlaySoundAt(new AssetLocation("sounds/effect/extinguish"), FirePos.X + 0.5, FirePos.Y, FirePos.Z + 0.5, null, false, 16);

                    if (rand.NextDouble() < rain / 2)
                    {
                        KillFire(false);
                        return;
                    }
                }
            }
        }
Beispiel #3
0
        private void OnSlowTick(float dt)
        {
            if (Api.Side == EnumAppSide.Client)
            {
                return;
            }

            BlockPos neibPos = Pos.AddCopy(fromFacing.Opposite);

            neibBlock = Api.World.BlockAccessor.GetBlock(neibPos);
            if (!canBurn(neibBlock, neibPos))
            {
                Api.World.BlockAccessor.SetBlock(0, Pos);
                Api.World.BlockAccessor.TriggerNeighbourBlockUpdate(Pos);
                return;
            }

            Entity[] entities = Api.World.GetEntitiesAround(Pos.ToVec3d().Add(0.5, 0.5, 0.5), 3, 3, (e) => e.Alive);
            Vec3d    ownPos   = Pos.ToVec3d();

            for (int i = 0; i < entities.Length; i++)
            {
                Entity entity = entities[i];
                if (CollisionTester.AabbIntersect(entity.CollisionBox, entity.ServerPos.X, entity.ServerPos.Y, entity.ServerPos.Z, fireCuboid, ownPos))
                {
                    entity.ReceiveDamage(new DamageSource()
                    {
                        Source = EnumDamageSource.Block, SourceBlock = fireBlock, SourcePos = ownPos, Type = EnumDamageType.Fire
                    }, 2f);
                }
            }


            if (Api.World.BlockAccessor.GetRainMapHeightAt(Pos.X, Pos.Y) <= Pos.Y)   // It's more efficient to do this quick check before GetPrecipitation
            {
                // Die on rainfall
                tmpPos.Set(Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5);
                double rain = wsys.GetPrecipitation(tmpPos);
                if (rain > 0.1)
                {
                    Api.World.PlaySoundAt(new AssetLocation("sounds/effect/extinguish"), Pos.X + 0.5, Pos.Y, Pos.Z + 0.5, null, false, 16);

                    if (rand.NextDouble() < rain / 2)
                    {
                        Api.World.BlockAccessor.SetBlock(0, Pos);
                        Api.World.BlockAccessor.TriggerNeighbourBlockUpdate(Pos);
                        return;
                    }
                }
            }
        }
        public bool shouldExtinguishFromRainFall(out float rainLevel)
        {
            rainLevel = 0;
            if (Api.Side == EnumAppSide.Server && IsBurning && Api.World.Rand.NextDouble() > 0.5)
            {
                if (Api.World.BlockAccessor.GetRainMapHeightAt(Pos.X, Pos.Z) <= Pos.Y)   // It's more efficient to do this quick check before GetPrecipitation
                {
                    // Die on rainfall
                    tmpPos.Set(Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5);
                    rainLevel = wsys.GetPrecipitation(tmpPos);
                    if (rainLevel > 0.04 && Api.World.Rand.NextDouble() < rainLevel * 5)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns>true if it was a longer interval check (checked rain as well) so that an UpdateFarmlandBlock() is advisable</returns>
        bool updateMoistureLevel(double totalDays, float waterDistance, bool skyExposed, ClimateCondition baseClimate = null)
        {
            tmpPos.Set(Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5);

            double hoursPassed = Math.Min((totalDays - lastMoistureLevelUpdateTotalDays) * Api.World.Calendar.HoursPerDay, 48);

            if (hoursPassed < 0.03f)
            {
                // Get wet from a water source
                moistureLevel = Math.Max(moistureLevel, GameMath.Clamp(1 - waterDistance / 4f, 0, 1));

                return(false);
            }

            // Dry out
            moistureLevel = Math.Max(0, moistureLevel - (float)hoursPassed / 48f);

            // Get wet from a water source
            moistureLevel = Math.Max(moistureLevel, GameMath.Clamp(1 - waterDistance / 4f, 0, 1));

            // Get wet from all the rainfall since last update
            if (skyExposed)
            {
                if (baseClimate == null && hoursPassed > 0)
                {
                    baseClimate = Api.World.BlockAccessor.GetClimateAt(Pos, EnumGetClimateMode.WorldGenValues, totalDays - hoursPassed * Api.World.Calendar.HoursPerDay / 2);
                }
                while (hoursPassed > 0)
                {
                    double rainLevel = wsys.GetPrecipitation(Pos, totalDays - hoursPassed * Api.World.Calendar.HoursPerDay, baseClimate);
                    moistureLevel = GameMath.Clamp(moistureLevel + (float)rainLevel / 3f, 0, 1);
                    hoursPassed--;
                }
            }

            lastMoistureLevelUpdateTotalDays = totalDays;

            return(true);
        }
Beispiel #6
0
        bool updateMoistureLevel(double totalDays, float waterDistance)
        {
            tmpPos.Set(Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5);

            double hoursPassed = Math.Min((totalDays - lastMoistureLevelUpdateTotalDays) * Api.World.Calendar.HoursPerDay, 48);

            if (hoursPassed < 0.03f)
            {
                // Get wet from a water source
                moistureLevel = Math.Max(moistureLevel, GameMath.Clamp(1 - waterDistance / 4f, 0, 1));

                return(true);
            }

            // Dry out
            moistureLevel = Math.Max(0, moistureLevel - (float)hoursPassed / 48f);

            // Get wet from a water source
            moistureLevel = Math.Max(moistureLevel, GameMath.Clamp(1 - waterDistance / 4f, 0, 1));

            // Get wet from all the rainfall since last update
            if (Api.World.BlockAccessor.GetRainMapHeightAt(Pos.X, Pos.Z) <= Pos.Y + 1)
            {
                while (hoursPassed > 0)
                {
                    double rainLevel = wsys.GetPrecipitation(tmpPos.X, tmpPos.Y, tmpPos.Z, totalDays - hoursPassed * Api.World.Calendar.HoursPerDay);
                    moistureLevel = GameMath.Clamp(moistureLevel + (float)rainLevel / 3f, 0, 1);
                    hoursPassed--;
                }
            }

            UpdateFarmlandBlock();

            lastMoistureLevelUpdateTotalDays = totalDays;

            return(true);
        }
Beispiel #7
0
        // Sync to client every 500ms
        private void On500msTick(float dt)
        {
            if (Api is ICoreServerAPI && (IsBurning || prevFurnaceTemperature != furnaceTemperature))
            {
                MarkDirty();
            }

            prevFurnaceTemperature = furnaceTemperature;

            if (Api.Side == EnumAppSide.Server && IsBurning && Api.World.Rand.NextDouble() > 0.5)
            {
                if (Api.World.BlockAccessor.GetRainMapHeightAt(Pos.X, Pos.Z) <= Pos.Y)   // It's more efficient to do this quick check before GetPrecipitation
                {
                    // Die on rainfall
                    tmpPos.Set(Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5);
                    double rainLevel = wsys.GetPrecipitation(tmpPos);
                    if (rainLevel > 0.04 && Api.World.Rand.NextDouble() < rainLevel * 5)
                    {
                        Api.World.PlaySoundAt(new AssetLocation("sounds/effect/extinguish"), Pos.X + 0.5, Pos.Y, Pos.Z + 0.5, null, false, 16);

                        fuelBurnTime -= (float)rainLevel / 10f;

                        if (Api.World.Rand.NextDouble() < rainLevel / 5f || fuelBurnTime <= 0)
                        {
                            setBlockState("cold");
                            extinguishedTotalHours = -99;
                            canIgniteFuel          = false;
                            fuelBurnTime           = 0;
                            maxFuelBurnTime        = 0;
                        }

                        MarkDirty(true);
                    }
                }
            }
        }
Beispiel #8
0
        private void OnCommonTick(float dt)
        {
            if (burning)
            {
                double hoursPassed = Api.World.Calendar.TotalHours - lastTickTotalHours;

                if (fuelLevel > 0)
                {
                    fuelLevel = Math.Max(0, fuelLevel - (float)(2.5 / 24 * hoursPassed));
                }

                if (fuelLevel <= 0)
                {
                    burning = false;
                }

                if (contents != null)
                {
                    float temp = contents.Collectible.GetTemperature(Api.World, contents);
                    if (temp < 1100)
                    {
                        float tempGain = (float)(hoursPassed * 1500);

                        contents.Collectible.SetTemperature(Api.World, contents, Math.Min(1100, temp + tempGain));
                    }
                }
            }


            tmpPos.Set(Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5);
            double rainLevel = 0;
            bool   rainCheck =
                Api.Side == EnumAppSide.Server &&
                Api.World.Rand.NextDouble() < 0.15 &&
                Api.World.BlockAccessor.GetRainMapHeightAt(Pos.X, Pos.Z) <= Pos.Y &&
                (rainLevel = wsys.GetPrecipitation(tmpPos)) > 0.1
            ;

            if (rainCheck && Api.World.Rand.NextDouble() < rainLevel * 5)
            {
                bool playsound = false;
                if (burning)
                {
                    playsound  = true;
                    fuelLevel -= (float)rainLevel / 250f;
                    if (Api.World.Rand.NextDouble() < rainLevel / 30f || fuelLevel <= 0)
                    {
                        burning = false;
                    }
                    MarkDirty(true);
                }


                float temp = contents == null ? 0 : contents.Collectible.GetTemperature(Api.World, contents);
                if (temp > 20)
                {
                    playsound = temp > 100;
                    contents.Collectible.SetTemperature(Api.World, contents, Math.Min(1100, temp - 8), false);
                    MarkDirty(true);
                }

                if (playsound)
                {
                    Api.World.PlaySoundAt(new AssetLocation("sounds/effect/extinguish"), Pos.X + 0.5, Pos.Y + 0.75, Pos.Z + 0.5, null, false, 16);
                }
            }

            lastTickTotalHours = Api.World.Calendar.TotalHours;
        }