Beispiel #1
0
        public override bool ShouldExecute()
        {
            // React immediately on hurt, otherwise only 1/10 chance of execution
            if (rand.NextDouble() > 0.1f && (whenInEmotionState == null || bhEmo?.IsInEmotionState(whenInEmotionState) != true))
            {
                return(false);
            }

            if (whenInEmotionState != null && bhEmo?.IsInEmotionState(whenInEmotionState) != true)
            {
                return(false);
            }
            if (whenNotInEmotionState != null && bhEmo?.IsInEmotionState(whenNotInEmotionState) == true)
            {
                return(false);
            }
            if (whenInEmotionState == null && rand.NextDouble() > 0.5f)
            {
                return(false);
            }
            if (cooldownUntilMs > entity.World.ElapsedMilliseconds)
            {
                return(false);
            }

            float range = maxDist;

            lastSearchTotalMs = entity.World.ElapsedMilliseconds;
            Vec3d ownPos = entity.ServerPos.XYZ;

            targetEntity = partitionUtil.GetNearestEntity(entity.ServerPos.XYZ, range, (e) => IsTargetableEntity(e, range) && hasDirectContact(e, range, range / 2f));

            return(targetEntity != null);
        }
        public override bool ShouldExecute()
        {
            // React immediately on hurt, otherwise only 1/10 chance of execution
            if (rand.NextDouble() > 0.1f && (whenInEmotionState == null || !entity.HasEmotionState(whenInEmotionState)))
            {
                return(false);
            }

            if (whenInEmotionState != null && !entity.HasEmotionState(whenInEmotionState))
            {
                return(false);
            }
            if (whenNotInEmotionState != null && entity.HasEmotionState(whenNotInEmotionState))
            {
                return(false);
            }
            if (lastSearchTotalMs + 4000 > entity.World.ElapsedMilliseconds)
            {
                return(false);
            }
            if (whenInEmotionState == null && rand.NextDouble() > 0.5f)
            {
                return(false);
            }


            if (jumpAnimOn && entity.World.ElapsedMilliseconds - finishedMs > 2000)
            {
                entity.AnimManager.StopAnimation("jump");
            }

            if (cooldownUntilMs > entity.World.ElapsedMilliseconds)
            {
                return(false);
            }

            if (belowTempThreshold > -99)
            {
                ClimateCondition conds = entity.World.BlockAccessor.GetClimateAt(entity.Pos.AsBlockPos, EnumGetClimateMode.NowValues);
                lowTempMode = conds != null && conds.Temperature <= belowTempThreshold;
            }

            float range = lowTempMode ? belowTempSeekingRange : seekingRange;


            lastSearchTotalMs = entity.World.ElapsedMilliseconds;

            Vec3d ownPos = entity.ServerPos.XYZ;

            targetEntity = (EntityAgent)partitionUtil.GetNearestEntity(entity.ServerPos.XYZ, range, (e) => {
                if (!e.Alive || !e.IsInteractable || e.EntityId == this.entity.EntityId)
                {
                    return(false);
                }

                for (int i = 0; i < seekEntityCodesExact.Length; i++)
                {
                    if (e.Code.Path == seekEntityCodesExact[i])
                    {
                        if (e.Code.Path == "player")
                        {
                            float rangeMul = e.Stats.GetBlended("animalSeekingRange");

                            IPlayer player = entity.World.PlayerByUid(((EntityPlayer)e).PlayerUID);
                            return
                            ((rangeMul == 1 || e.ServerPos.DistanceTo(ownPos) < range * rangeMul) &&
                             (player == null || (player.WorldData.CurrentGameMode != EnumGameMode.Creative && player.WorldData.CurrentGameMode != EnumGameMode.Spectator && (player as IServerPlayer).ConnectionState == EnumClientState.Playing))
                            );
                        }
                        return(true);
                    }
                }


                for (int i = 0; i < seekEntityCodesBeginsWith.Length; i++)
                {
                    if (e.Code.Path.StartsWithFast(seekEntityCodesBeginsWith[i]))
                    {
                        return(true);
                    }
                }

                return(false);
            });



            if (targetEntity != null)
            {
                if (alarmHerd && entity.HerdId > 0)
                {
                    entity.World.GetNearestEntity(entity.ServerPos.XYZ, range, range, (e) =>
                    {
                        EntityAgent agent = e as EntityAgent;
                        if (e.EntityId != entity.EntityId && agent != null && agent.Alive && agent.HerdId == entity.HerdId)
                        {
                            agent.Notify("seekEntity", targetEntity);
                        }

                        return(false);
                    });
                }

                targetPos = targetEntity.ServerPos.XYZ;

                if (entity.ServerPos.SquareDistanceTo(targetPos) <= MinDistanceToTarget())
                {
                    return(false);
                }

                return(true);
            }

            return(false);
        }
        public override bool ShouldExecute()
        {
            if (rand.NextDouble() > 0.1f)
            {
                return(false);                          // was 0.04 before, but that made creatures react very slowly when in emotionstate aggressiveondamage. So lets double the reaction time when in that emotion state
            }
            if (whenInEmotionState != null && !entity.HasEmotionState(whenInEmotionState))
            {
                return(false);
            }
            if (whenNotInEmotionState != null && entity.HasEmotionState(whenNotInEmotionState))
            {
                return(false);
            }
            if (lastSearchTotalMs + 4000 > entity.World.ElapsedMilliseconds)
            {
                return(false);
            }
            if (whenInEmotionState == null && rand.NextDouble() > 0.5f)
            {
                return(false);
            }


            if (jumpAnimOn && entity.World.ElapsedMilliseconds - finishedMs > 2000)
            {
                entity.AnimManager.StopAnimation("jump");
            }

            if (cooldownUntilMs > entity.World.ElapsedMilliseconds)
            {
                return(false);
            }


            lastSearchTotalMs = entity.World.ElapsedMilliseconds;

            targetEntity = (EntityAgent)partitionUtil.GetNearestEntity(entity.ServerPos.XYZ, seekingRange, (e) => {
                if (!e.Alive || !e.IsInteractable || e.EntityId == this.entity.EntityId)
                {
                    return(false);
                }

                for (int i = 0; i < seekEntityCodesExact.Length; i++)
                {
                    if (e.Code.Path == seekEntityCodesExact[i])
                    {
                        if (e.Code.Path == "player")
                        {
                            IPlayer player = entity.World.PlayerByUid(((EntityPlayer)e).PlayerUID);
                            return
                            (player == null ||
                             (player.WorldData.CurrentGameMode != EnumGameMode.Creative && player.WorldData.CurrentGameMode != EnumGameMode.Spectator && (player as IServerPlayer).ConnectionState == EnumClientState.Playing));
                        }
                        return(true);
                    }
                }


                for (int i = 0; i < seekEntityCodesBeginsWith.Length; i++)
                {
                    if (e.Code.Path.StartsWithFast(seekEntityCodesBeginsWith[i]))
                    {
                        return(true);
                    }
                }

                return(false);
            });



            if (targetEntity != null)
            {
                if (alarmHerd && entity.HerdId > 0)
                {
                    entity.World.GetNearestEntity(entity.ServerPos.XYZ, seekingRange, seekingRange, (e) =>
                    {
                        EntityAgent agent = e as EntityAgent;
                        if (e.EntityId != entity.EntityId && agent != null && agent.Alive && agent.HerdId == entity.HerdId)
                        {
                            agent.Notify("seekEntity", targetEntity);
                        }

                        return(false);
                    });
                }

                targetPos = targetEntity.ServerPos.XYZ;

                if (entity.ServerPos.SquareDistanceTo(targetPos) <= MinDistanceToTarget())
                {
                    return(false);
                }

                return(true);
            }

            return(false);
        }
Beispiel #4
0
        public override bool ShouldExecute()
        {
            if (noEntityCodes && (attackedByEntity == null || !retaliateAttacks))
            {
                return(false);
            }

            // React immediately on hurt, otherwise only 1/10 chance of execution
            if (rand.NextDouble() > 0.1f && (whenInEmotionState == null || bhEmo?.IsInEmotionState(whenInEmotionState) != true) && !RecentlyAttacked)
            {
                return(false);
            }

            if (whenInEmotionState != null && bhEmo?.IsInEmotionState(whenInEmotionState) != true)
            {
                return(false);
            }
            if (whenNotInEmotionState != null && bhEmo?.IsInEmotionState(whenNotInEmotionState) == true)
            {
                return(false);
            }
            if (lastSearchTotalMs + searchWaitMs > entity.World.ElapsedMilliseconds)
            {
                return(false);
            }
            if (whenInEmotionState == null && rand.NextDouble() > 0.5f)
            {
                return(false);
            }
            if (jumpAnimOn && entity.World.ElapsedMilliseconds - finishedMs > 2000)
            {
                entity.AnimManager.StopAnimation("jump");
            }

            if (cooldownUntilMs > entity.World.ElapsedMilliseconds && !RecentlyAttacked)
            {
                return(false);
            }

            if (belowTempThreshold > -99)
            {
                ClimateCondition conds = entity.World.BlockAccessor.GetClimateAt(entity.Pos.AsBlockPos, EnumGetClimateMode.NowValues);
                lowTempMode = conds != null && conds.Temperature <= belowTempThreshold;
            }

            float range = NowSeekRange;

            lastSearchTotalMs = entity.World.ElapsedMilliseconds;

            if (!RecentlyAttacked)
            {
                attackedByEntity = null;
            }

            if (retaliateAttacks && attackedByEntity != null && attackedByEntity.Alive && IsTargetableEntity(attackedByEntity, range, true))
            {
                targetEntity = attackedByEntity;
                targetPos    = targetEntity.ServerPos.XYZ;
                return(true);
            }
            else
            {
                ownPos.Set(entity.ServerPos);
                targetEntity = partitionUtil.GetNearestEntity(ownPos, range, (e) => IsTargetableEntity(e, range));

                if (targetEntity != null)
                {
                    if (alarmHerd && entity.HerdId > 0)
                    {
                        entity.World.GetNearestEntity(ownPos, range, range, (e) =>
                        {
                            EntityAgent agent = e as EntityAgent;
                            if (e.EntityId != entity.EntityId && agent != null && agent.Alive && agent.HerdId == entity.HerdId)
                            {
                                agent.Notify("seekEntity", targetEntity);
                            }

                            return(false);
                        });
                    }

                    targetPos = targetEntity.ServerPos.XYZ;
                    if (entity.ServerPos.SquareDistanceTo(targetPos) <= MinDistanceToTarget())
                    {
                        return(false);
                    }

                    return(true);
                }
            }

            return(false);
        }
        public override bool ShouldExecute()
        {
            soundChance = Math.Min(1.01f, soundChance + 1 / 500f);

            if (rand.NextDouble() > 2 * executionChance)
            {
                return(false);
            }
            if (noEntityCodes && (attackedByEntity == null || !retaliateAttacks))
            {
                return(false);
            }

            if (whenInEmotionState != null && bhEmo?.IsInEmotionState(whenInEmotionState) != true)
            {
                return(false);
            }
            if (whenNotInEmotionState != null && bhEmo?.IsInEmotionState(whenNotInEmotionState) == true)
            {
                return(false);
            }

            // Double exec chance, but therefore halved here again to increase response speed for creature when aggressive
            if (whenInEmotionState == null && rand.NextDouble() > 0.5f)
            {
                return(false);
            }

            // This code section controls drifter behavior - they retreat (flee slowly) from the player in the daytime, this is "switched off" below ground or at night, also switched off in temporal storms
            // Has to be checked every tick because the drifter attributes change during temporal storms  (grrr, this is a slow way to do it)
            if (!entity.Attributes.GetBool("ignoreDaylightFlee", false))
            {
                if (ignoreDeepDayLight && entity.ServerPos.Y < world.SeaLevel - 2)
                {
                    return(false);
                }

                float sunlight = entity.World.BlockAccessor.GetLightLevel((int)entity.ServerPos.X, (int)entity.ServerPos.Y, (int)entity.ServerPos.Z, EnumLightLevelType.TimeOfDaySunLight) / (float)entity.World.SunBrightness;
                if (sunlight < minDayLight)
                {
                    return(false);
                }
            }

            int   generation          = entity.WatchedAttributes.GetInt("generation", 0);
            float fearReductionFactor = (whenInEmotionState != null) ? 1 : Math.Max(0f, (tamingGenerations - generation) / tamingGenerations);

            ownPos.Set(entity.ServerPos);
            float hereRange = fearReductionFactor * seekingRange;

            targetEntity = (EntityAgent)partitionUtil.GetNearestEntity(ownPos, hereRange, (e) => {
                if (!IsTargetableEntity(e, hereRange))
                {
                    return(false);
                }
                if (!(e is EntityPlayer) || !lowStabilityAttracted)
                {
                    return(true);
                }
                return(e.WatchedAttributes.GetDouble("temporalStability", 1) < 0.25);
            });


            if (targetEntity != null)
            {
                updateTargetPosFleeMode(targetPos);
                return(true);
            }

            return(false);
        }
        public override bool ShouldExecute()
        {
            soundChance = Math.Min(1.01f, soundChance + 1 / 500f);

            if (rand.NextDouble() > 2 * executionChance)
            {
                return(false);
            }


            if (whenInEmotionState != null && !entity.HasEmotionState(whenInEmotionState))
            {
                return(false);
            }
            if (whenNotInEmotionState != null && entity.HasEmotionState(whenNotInEmotionState))
            {
                return(false);
            }

            // Double exec chance, but therefore halved here again to increase response speed for creature when aggressive
            if (whenInEmotionState == null && rand.NextDouble() > 0.5f)
            {
                return(false);
            }

            float sunlight = entity.World.BlockAccessor.GetLightLevel((int)entity.ServerPos.X, (int)entity.ServerPos.Y, (int)entity.ServerPos.Z, EnumLightLevelType.TimeOfDaySunLight) / (float)entity.World.SunBrightness;

            if ((ignoreDeepDayLight && entity.ServerPos.Y < world.SeaLevel - 2) || sunlight < minDayLight)
            {
                if (!entity.Attributes.GetBool("ignoreDaylightFlee", false))
                {
                    return(false);
                }
            }

            int   generation          = entity.WatchedAttributes.GetInt("generation", 0);
            float fearReductionFactor = Math.Max(0f, (10f - generation) / 10f);

            if (whenInEmotionState != null)
            {
                fearReductionFactor = 1;
            }

            Vec3d  ownPos    = entity.ServerPos.XYZ;
            double hereRange = fearReductionFactor * seekingRange;

            targetEntity = (EntityAgent)partitionUtil.GetNearestEntity(ownPos, hereRange, (e) => {
                if (!e.Alive || e.EntityId == this.entity.EntityId || e is EntityItem)
                {
                    return(false);
                }

                for (int i = 0; i < fleeEntityCodesExact.Length; i++)
                {
                    if (e.Code.Path == fleeEntityCodesExact[i])
                    {
                        if (e is EntityAgent eagent)
                        {
                            float rangeMul = 1f;

                            // Sneaking reduces the detection range
                            if (eagent.Controls.Sneak && eagent.OnGround)
                            {
                                rangeMul *= 0.6f;
                            }
                            // Trait bonus
                            if (e.Code.Path == "player")
                            {
                                rangeMul *= eagent.Stats.GetBlended("animalSeekingRange");
                            }

                            if (rangeMul != 1 && e.ServerPos.DistanceTo(ownPos) > hereRange * rangeMul)
                            {
                                return(false);
                            }
                        }

                        if (e.Code.Path == "player")
                        {
                            IPlayer player = entity.World.PlayerByUid(((EntityPlayer)e).PlayerUID);
                            bool ok        = player == null || (player.WorldData.CurrentGameMode != EnumGameMode.Creative && player.WorldData.CurrentGameMode != EnumGameMode.Spectator);

                            ok &= !lowStabilityAttracted || e.WatchedAttributes.GetDouble("temporalStability", 1) > 0.25;

                            return(ok);
                        }
                        return(true);
                    }
                }

                for (int i = 0; i < fleeEntityCodesBeginsWith.Length; i++)
                {
                    if (e.Code.Path.StartsWithFast(fleeEntityCodesBeginsWith[i]))
                    {
                        return(true);
                    }
                }

                return(false);
            });

            //yawOffset = 0;

            if (targetEntity != null)
            {
                updateTargetPos();

                return(true);
            }

            return(false);
        }
        public override bool ShouldExecute()
        {
            soundChance = Math.Min(1.01f, soundChance + 1 / 500f);

            if (rand.NextDouble() > 2 * executionChance)
            {
                return(false);
            }


            if (entity.World.Calendar.DayLightStrength < minDayLight)
            {
                return(false);
            }
            if (whenInEmotionState != null && !entity.HasEmotionState(whenInEmotionState))
            {
                return(false);
            }
            if (whenNotInEmotionState != null && entity.HasEmotionState(whenNotInEmotionState))
            {
                return(false);
            }

            // Double exec chance, but therefore halved here again to increase response speed for creature when aggressive
            if (whenInEmotionState == null && rand.NextDouble() > 0.5f)
            {
                return(false);
            }


            int   generation          = entity.WatchedAttributes.GetInt("generation", 0);
            float fearReductionFactor = Math.Max(0f, (10f - generation) / 10f);

            if (whenInEmotionState != null)
            {
                fearReductionFactor = 1;
            }

            targetEntity = (EntityAgent)partitionUtil.GetNearestEntity(entity.ServerPos.XYZ, fearReductionFactor * seekingRange, (e) => {
                if (!e.Alive || e.EntityId == this.entity.EntityId || e is EntityItem)
                {
                    return(false);
                }

                for (int i = 0; i < fleeEntityCodesExact.Length; i++)
                {
                    if (e.Code.Path == fleeEntityCodesExact[i])
                    {
                        if (e.Code.Path == "player")
                        {
                            IPlayer player = entity.World.PlayerByUid(((EntityPlayer)e).PlayerUID);
                            bool ok        = player == null || (player.WorldData.CurrentGameMode != EnumGameMode.Creative && player.WorldData.CurrentGameMode != EnumGameMode.Spectator);

                            ok &= !lowStabilityAttracted || e.WatchedAttributes.GetDouble("temporalStability", 1) > 0.25;

                            return(ok);
                        }
                        return(true);
                    }
                }

                for (int i = 0; i < fleeEntityCodesBeginsWith.Length; i++)
                {
                    if (e.Code.Path.StartsWithFast(fleeEntityCodesBeginsWith[i]))
                    {
                        return(true);
                    }
                }

                return(false);
            });

            //yawOffset = 0;

            if (targetEntity != null)
            {
                updateTargetPos();

                return(true);
            }

            return(false);
        }