예제 #1
0
        public override void FinishExecute(bool cancelled)
        {
            base.FinishExecute(cancelled);
            attemptLayEggTotalHours = -1;
            pathTraverser.Stop();

            if (sitAnimMeta != null)
            {
                entity.AnimManager.StopAnimation(sitAnimMeta.Code);
            }

            targetPoi?.SetOccupier(null);

            if (cancelled)
            {
                cooldownUntilTotalHours = 0;
            }
        }
예제 #2
0
        public override bool ContinueExecute(float dt)
        {
            if (targetPoi.Occupied(entity))
            {
                onBadTarget();
                return(false);
            }

            Vec3d  pos      = targetPoi.Position;
            double distance = pos.HorizontalSquareDistanceTo(entity.ServerPos.X, entity.ServerPos.Z);

            pathTraverser.CurrentTarget.X = pos.X;
            pathTraverser.CurrentTarget.Y = pos.Y;
            pathTraverser.CurrentTarget.Z = pos.Z;

            //Cuboidd targetBox = entity.CollisionBox.ToDouble().Translate(entity.ServerPos.X, entity.ServerPos.Y, entity.ServerPos.Z);
            //double distance = targetBox.ShortestDistanceFrom(pos);

            float minDist = MinDistanceToTarget();

            if (distance <= minDist)
            {
                pathTraverser.Stop();
                if (animMeta != null)
                {
                    entity.AnimManager.StopAnimation(animMeta.Code);
                }

                EntityBehaviorMultiply bh = entity.GetBehavior <EntityBehaviorMultiply>();

                if (targetPoi.IsSuitableFor(entity) != true)
                {
                    onBadTarget();
                    return(false);
                }

                targetPoi.SetOccupier(entity);

                if (sitAnimMeta != null && !sitAnimStarted)
                {
                    entity.AnimManager.StartAnimation(sitAnimMeta);

                    sitAnimStarted = true;
                    sitEndDay      = entity.World.Calendar.TotalDays + sitDays;
                }

                sitTimeNow += dt;

                if (sitTimeNow >= layTime && !laid)
                {
                    laid = true;

                    // Potential gameplay/realism issue: the rooster has to be nearby at the exact moment the egg is laid, instead of looking to see whether there was a rooster / hen interaction ;) recently ...
                    // To mitigate this issue, we increase the rooster search range to 9 blocks in the JSON
                    if (targetPoi.TryAddEgg(entity, GetRequiredEntityNearby() == null ? null : chickCode, incubationDays))
                    {
                        ConsumeFood(PortionsEatenForLay);
                        attemptLayEggTotalHours = -1;
                        MakeLaySound();
                        failedSeekTargets.Remove(targetPoi);
                        return(false);
                    }
                }

                // Stop sitting - this allows a broody hen to go and eat for example
                if (entity.World.Calendar.TotalDays >= sitEndDay)
                {
                    failedSeekTargets.Remove(targetPoi);
                    return(false);
                }
            }
            else
            {
                if (!pathTraverser.Active)
                {
                    float rndx = (float)entity.World.Rand.NextDouble() * 0.3f - 0.15f;
                    float rndz = (float)entity.World.Rand.NextDouble() * 0.3f - 0.15f;
                    pathTraverser.NavigateTo(targetPoi.Position.AddCopy(rndx, 0, rndz), moveSpeed, MinDistanceToTarget() - 0.15f, OnGoalReached, OnStuck, false, 500);
                }
            }


            if (nowStuck)
            {
                return(false);
            }

            if (attemptLayEggTotalHours > 0 && entity.World.Calendar.TotalHours - attemptLayEggTotalHours > 12)
            {
                LayEggOnGround();
                return(false);
            }


            return(true);
        }