Ejemplo n.º 1
0
        public override void OnGameTick(float deltaTime)
        {
            if (entity.Pos.Y < -30)
            {
                entity.ReceiveDamage(new DamageSource()
                {
                    Source = EnumDamageSource.Void,
                    Type   = EnumDamageType.Gravity
                }, 4);
            }

            secondsSinceLastUpdate += deltaTime;

            if (secondsSinceLastUpdate >= 1)
            {
                secondsSinceLastUpdate = 0;

                if (entity.Alive && Health < MaxHealth)
                {
                    float recoverySpeed = 0.01f;

                    EntityBehaviorHunger ebh = entity.GetBehavior <EntityBehaviorHunger>();

                    if (ebh != null)
                    {
                        EntityPlayer plr = (EntityPlayer)entity;
                        if (plr != null && entity.World.PlayerByUid(plr.PlayerUID).WorldData.CurrentGameMode == EnumGameMode.Creative)
                        {
                            return;
                        }

                        // When below 75% satiety, autoheal starts dropping
                        recoverySpeed = GameMath.Clamp(0.01f * ebh.Saturation / ebh.MaxSaturation * 1 / 0.75f, 0, 0.01f);

                        ebh.ConsumeSaturation(150f * recoverySpeed);
                    }

                    Health = Math.Min(Health + recoverySpeed, MaxHealth);
                }

                int rainy = entity.World.BlockAccessor.GetRainMapHeightAt((int)entity.ServerPos.X, (int)entity.ServerPos.Z);
                if (entity.World.Side == EnumAppSide.Server && entity is EntityPlayer && rainy <= entity.ServerPos.Y)
                {
                    WeatherSystemBase wsys = entity.Api.ModLoader.GetModSystem <WeatherSystemBase>();
                    var state = wsys.GetPrecipitationState(entity.ServerPos.XYZ);

                    if (state != null && state.ParticleSize > 0.6 && state.Type == EnumPrecipitationType.Hail && entity.World.Rand.NextDouble() < state.Level / 2)
                    {
                        entity.ReceiveDamage(new DamageSource()
                        {
                            Source = EnumDamageSource.Weather,
                            Type   = EnumDamageType.BluntAttack
                        }, (float)state.ParticleSize / 15f);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public override void OnGameTick(float deltaTime)
        {
            entity.World.FrameProfiler.Mark("not-bhhealth");
            if (entity.Pos.Y < -30)
            {
                entity.ReceiveDamage(new DamageSource()
                {
                    Source = EnumDamageSource.Void,
                    Type   = EnumDamageType.Gravity
                }, 4);
            }

            secondsSinceLastUpdate += deltaTime;

            if (secondsSinceLastUpdate >= 1)
            {
                secondsSinceLastUpdate = 0;

                if (entity.Alive)
                {
                    float health    = Health; // higher performance to read this TreeAttribute only once
                    float maxHealth = MaxHealth;
                    if (health < maxHealth)
                    {
                        float recoverySpeed = 0.01f;

                        // Only players have the hunger behavior, and the different nutrient saturations
                        if (entity is EntityPlayer plr)
                        {
                            EntityBehaviorHunger ebh = entity.GetBehavior <EntityBehaviorHunger>();

                            if (ebh != null)
                            {
                                if (entity.World.PlayerByUid(plr.PlayerUID).WorldData.CurrentGameMode == EnumGameMode.Creative)
                                {
                                    return;
                                }

                                // When below 75% satiety, autoheal starts dropping
                                recoverySpeed = GameMath.Clamp(0.01f * ebh.Saturation / ebh.MaxSaturation * 1 / 0.75f, 0, 0.01f);

                                ebh.ConsumeSaturation(150f * recoverySpeed);
                            }
                        }

                        Health = Math.Min(health + recoverySpeed, maxHealth);
                    }
                }

                if (entity is EntityPlayer && entity.World.Side == EnumAppSide.Server)
                {
                    // A costly check every 1s for hail damage, but it applies only to players who are in the open

                    int rainy = entity.World.BlockAccessor.GetRainMapHeightAt((int)entity.ServerPos.X, (int)entity.ServerPos.Z);
                    if (entity.ServerPos.Y >= rainy)
                    {
                        WeatherSystemBase wsys = entity.Api.ModLoader.GetModSystem <WeatherSystemBase>();
                        var state = wsys.GetPrecipitationState(entity.ServerPos.XYZ);

                        if (state != null && state.ParticleSize >= 0.5 && state.Type == EnumPrecipitationType.Hail && entity.World.Rand.NextDouble() < state.Level / 2)
                        {
                            entity.ReceiveDamage(new DamageSource()
                            {
                                Source = EnumDamageSource.Weather,
                                Type   = EnumDamageType.BluntAttack
                            }, (float)state.ParticleSize / 15f);
                        }
                    }
                }
            }
        }