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); }
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(); }
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); } }
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); }
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); }); }
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); }