예제 #1
0
        public override bool ShouldExecute()
        {
            IPointOfInterest nearestPoi = porregistry.GetNearestPoi(entity.ServerPos.XYZ, 256, (poi) =>
            {
                target = poi as IPointOfInterest;
                if (poi.Type != "scary")
                {
                    return(false);
                }
                Vec3d pos         = target.Position;
                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)
                {
                    return(false);
                }

                if (target.Position != null)
                {
                    failedSeekTargets.TryGetValue(target, out FailedAttempt attempt);
                    if (attempt == null || (attempt.Count < 4 || attempt.LastTryMs < world.ElapsedMilliseconds - 60000))
                    {
                        return(true);
                    }
                }

                return(false);
            });


            return(nearestPoi != null);
        }
예제 #2
0
        private void WriteMapPoi(XmlWriter pathableWriter, IPointOfInterest pathable)
        {
            if (pathable.Type == PointOfInterestType.Route)
            {
                // TODO: Implement route writing
                throw new InvalidOperationException("Exporting routes is not currently supported.");
            }

            pathableWriter.WriteStartElement(pathable.Type == PointOfInterestType.Marker ? PackConstImpl.XML_ELEMENT_POI : PackConstImpl.XML_ELEMENT_TRAIL);

            pathableWriter.WriteAttributeString(PackConstImpl.XML_KNOWNATTRIBUTE_TYPE, pathable.ParentPathingCategory?.Namespace ?? "unspecified");

            foreach (var attribute in pathable.ExplicitAttributes)
            {
                if (this.PackWriterSettings.SkipMapId && attribute.Name == PackConstImpl.XML_KNOWNATTRIBUTE_MAPID)
                {
                    continue;
                }
                if (attribute.Name == PackConstImpl.XML_KNOWNATTRIBUTE_TYPE)
                {
                    continue;
                }
                pathableWriter.WriteAttributeString(attribute.Name, attribute.Value);
            }

            pathableWriter.WriteEndElement();
        }
예제 #3
0
        public override bool ShouldExecute()
        {
            EntityBehaviorProgram prog = entity.GetBehavior <EntityBehaviorProgram>();

            if (prog == null || prog.dormant)
            {
                return(false);
            }
            if (failureTime > entity.World.ElapsedMilliseconds || cooldownUntilMs > entity.World.ElapsedMilliseconds || !prog.CheckArea() || !CanPlant(entity.LeftHandItemSlot?.Itemstack?.Collectible))
            {
                return(false);
            }

            targetPoi = porregistry.GetNearestPoi((prog.workArea.End + prog.workArea.Start) / 2, (float)(prog.workArea.Length + prog.workArea.Height + prog.workArea.Width), (poi) =>
            {
                if (prog.workArea.ContainsOrTouches(poi.Position) && poi is BlockEntityFarmland && world.BlockAccessor.GetBlock(poi.Position.AsBlockPos).Replaceable > 9500)
                {
                    return(true);
                }


                return(false);
            });

            return(targetPoi != null);
        }
        public override bool ShouldExecute()
        {
            if (entity.World.Rand.NextDouble() < 0.005)
            {
                return(false);
            }
            if (cooldownUntilMs > entity.World.ElapsedMilliseconds)
            {
                return(false);
            }
            if (cooldownUntilTotalHours > entity.World.Calendar.TotalHours)
            {
                return(false);
            }
            if (whenInEmotionState != null && !entity.HasEmotionState(whenInEmotionState))
            {
                return(false);
            }
            if (whenNotInEmotionState != null && entity.HasEmotionState(whenNotInEmotionState))
            {
                return(false);
            }

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

            if (bh != null && !bh.ShouldEat)
            {
                return(false);
            }

            IPointOfInterest nearestPoi = porregistry.GetNearestPoi(entity.ServerPos.XYZ, 32, (poi) =>
            {
                if (poi.Type != "food")
                {
                    return(false);
                }

                if ((target = poi as IAnimalFoodSource)?.IsSuitableFor(entity) == true)
                {
                    FailedAttempt attempt;
                    failedSeekTargets.TryGetValue(target, out attempt);
                    doOnce = true;
                    if (attempt == null || (attempt.Count < 4 || attempt.LastTryMs < world.ElapsedMilliseconds - 60000))
                    {
                        return(true);
                    }
                }

                return(false);
            });


            return(nearestPoi != null);
        }
        public void RemovePOI(IPointOfInterest poi)
        {
            tmp.Set((int)poi.Position.X / chunksize, (int)poi.Position.Z / chunksize);

            List <IPointOfInterest> pois = null;

            PoisByChunkColumn.TryGetValue(tmp, out pois);
            if (pois != null)
            {
                pois.Remove(poi);
            }
        }
예제 #6
0
        private bool ShouldIgnorePathableType(IPointOfInterest pathable)
        {
            switch (pathable.Type)
            {
            case PointOfInterestType.Marker when !this.PackWriterSettings.IncludeMarkers:
            case PointOfInterestType.Trail when !this.PackWriterSettings.IncludeTrails:
            case PointOfInterestType.Route when !this.PackWriterSettings.IncludeRoutes:
                return(true);

            default:
                return(false);
            }
        }
        public void AddPOI(IPointOfInterest poi)
        {
            tmp.Set((int)poi.Position.X / chunksize, (int)poi.Position.Z / chunksize);

            List <IPointOfInterest> pois = null;

            PoisByChunkColumn.TryGetValue(tmp, out pois);
            if (pois == null)
            {
                PoisByChunkColumn[tmp] = pois = new List <IPointOfInterest>();
            }

            if (!pois.Contains(poi))
            {
                pois.Add(poi);
            }
        }
        public IPointOfInterest GetNearestPoi(Vec3d centerPos, float radius, PoiMatcher matcher = null)
        {
            int mincx = (int)(centerPos.X - radius) / chunksize;
            int mincz = (int)(centerPos.Z - radius) / chunksize;
            int maxcx = (int)(centerPos.X + radius) / chunksize;
            int maxcz = (int)(centerPos.Z + radius) / chunksize;

            float radiusSq = radius * radius;

            float            nearestDistSq = 9999999;
            IPointOfInterest nearestPoi    = null;

            for (int cx = mincx; cx <= maxcx; cx++)
            {
                for (int cz = mincz; cz <= maxcz; cz++)
                {
                    List <IPointOfInterest> pois = null;
                    tmp.Set(cx, cz);
                    PoisByChunkColumn.TryGetValue(tmp, out pois);
                    if (pois == null)
                    {
                        continue;
                    }

                    for (int i = 0; i < pois.Count; i++)
                    {
                        Vec3d poipos = pois[i].Position;
                        float distSq = poipos.SquareDistanceTo(centerPos);
                        if (distSq > radiusSq)
                        {
                            continue;
                        }

                        if (distSq < nearestDistSq && matcher(pois[i]))
                        {
                            nearestPoi    = pois[i];
                            nearestDistSq = distSq;
                        }
                    }
                }
            }

            return(nearestPoi);
        }
예제 #9
0
        private void StartCameraPan(IPointOfInterest pointOfInterest)
        {
            var focalPoint            = pointOfInterest.FocalPoint;
            var currentCameraPosition = View.transform.position;

            // If the camera is not far enough away from the point of interest, don't
            // move. We don't want to show and make the user wait for micro-movements of
            // the camera.
            var distanceFromFocalPoint = Vector3.Distance(currentCameraPosition, focalPoint);

            if (distanceFromFocalPoint <= pointOfInterest.Tolerance)
            {
                CameraPanCompleteSignal.Dispatch();
            }
            else
            {
                StartCoroutine(DoPan(focalPoint));
            }
        }
        public void SeekFoodSources(float dt)
        {
            shouldSeek = true;
            nearestPoi = porregistry.GetNearestPoi(entity.ServerPos.XYZ, 32, (poi) =>
            {
                if (poi.Type != "food")
                {
                    return(false);
                }

                if ((target = poi as IAnimalFoodSource)?.IsSuitableFor(entity) == true)
                {
                    FailedAttempt attempt;
                    failedSeekTargets.TryGetValue(target, out attempt);
                    doOnce = true;
                    if (attempt == null || (attempt.Count < 4 || attempt.LastTryMs < world.ElapsedMilliseconds - 60000))
                    {
                        return(true);
                    }
                }

                return(false);
            });
        }
예제 #11
0
        public IPointOfInterest GetWeightedNearestPoi(Vec3d centerPos, float radius, PoiMatcher matcher = null)
        {
            int mincx = (int)(centerPos.X - radius) / chunksize;
            int mincz = (int)(centerPos.Z - radius) / chunksize;
            int maxcx = (int)(centerPos.X + radius) / chunksize;
            int maxcz = (int)(centerPos.Z + radius) / chunksize;

            float radiusSq = radius * radius;

            float            nearestDistSq = 9999999;
            IPointOfInterest nearestPoi    = null;

            for (int cx = mincx; cx <= maxcx; cx++)
            {
                double chunkDistX = 0;  // x-distance from centerPos to nearest position in this chunk
                if (cx * chunksize > centerPos.X)
                {
                    chunkDistX = cx * chunksize - centerPos.X;
                }
                else if ((cx + 1) * chunksize < centerPos.X)
                {
                    chunkDistX = centerPos.X - (cx + 1) * chunksize;
                }

                for (int cz = mincz; cz <= maxcz; cz++)
                {
                    double cdistZ = 0;  // z-distance from centerPos to nearest position in this chunk
                    if (cz * chunksize > centerPos.Z)
                    {
                        cdistZ = cz * chunksize - centerPos.Z;
                    }
                    else if ((cz + 1) * chunksize < centerPos.Z)
                    {
                        cdistZ = centerPos.Z - (cz + 1) * chunksize;
                    }
                    if (chunkDistX * chunkDistX + cdistZ * cdistZ > nearestDistSq)
                    {
                        continue;                                                             // skip the search if this whole chunk is further than the nearest found so far
                    }
                    List <IPointOfInterest> pois = null;
                    tmp.Set(cx, cz);
                    PoisByChunkColumn.TryGetValue(tmp, out pois);
                    if (pois == null)
                    {
                        continue;
                    }

                    for (int i = 0; i < pois.Count; i++)
                    {
                        Vec3d poipos = pois[i].Position;
                        float weight = pois[i] is IAnimalNest nest ? nest.DistanceWeighting : 1f;
                        float distSq = poipos.SquareDistanceTo(centerPos) * weight;
                        if (distSq > radiusSq)
                        {
                            continue;
                        }

                        if (distSq < nearestDistSq && matcher(pois[i]))
                        {
                            nearestPoi    = pois[i];
                            nearestDistSq = distSq;
                        }
                    }
                }
            }

            return(nearestPoi);
        }