public override double Estimate() { if (GoalNode == null) { return(double.PositiveInfinity); } return(Vector3I.Distance(Cursor.GlobalPosition, GoalNode.Cursor.GlobalPosition)); }
/// <summary> /// Calculates path in current thread and returns the result /// </summary> /// <param name="start"></param> /// <param name="goal"></param> /// <returns></returns> public Path3D CalculatePath(Vector3I start, Vector3I goal) { var goalNode = new AStarNodeFunc3D(GetCursor(goal), null, 1); return(CalculateCustomPath(start, n => n.IsSameState(goalNode), AStarNodeFunc3D.GetSuccessors, n => Vector3I.Distance(n.Cursor.GlobalPosition, goal))); }
/// <summary> /// Npc will run away from the Dangerous entities /// </summary> public void RunAway() { if (Npc.DangerousEntities.Count == 0) { return; } // find the point maximally far from dangerous objects (run direction) _runAwayPoint = Npc.DangerousEntities.Select(e => { var escape = Npc.Character.Position - e.Position; escape.Normalize(); var value = 16 - Vector3D.Distance(e.Position, Npc.Character.Position); if (value <= 0) { return(Vector3D.Zero); } return(escape * value * 10); }).Aggregate((s, v) => s + v).ToCubePosition() + Npc.Character.Position.ToCubePosition(); _leader = null; Npc.Server.LandscapeManager.CalculateCustomPathAsync(Npc.DynamicEntity.Position.ToCubePosition(), n => Npc.DangerousEntities.All(e => Vector3I.Distance(n.Cursor.GlobalPosition, e.Position.ToCubePosition()) > 16), AStarNodeFunc3D.GetSuccessors, n => Vector3I.Distance(_runAwayPoint, n.Cursor.GlobalPosition), FollowPath); WaitingForPath = true; _runAway = true; }
private void SpawnTreeEntities(ServerChunk chunk, TreeSoul soul) { var config = _server.EntityFactory.Config; var treeBp = config.TreeBluePrintsDico[soul.TreeTypeId]; if (_server.Clock.Now - soul.LastItemsRegeneration < treeBp.ItemsRegenerationTime) { return; } List <BlockWithPosition> treeBlocks = null; soul.LastItemsRegeneration = _server.Clock.Now; foreach (var item in treeBp.StaticItems) { // check quantity limit var maxItems = _fastRandom.Next(item.Quantity.Min, item.Quantity.Max + 1); if (_server.LandscapeManager.AroundEntities(soul.Position, item.SpawningRange).Count(e => e.BluePrintId == item.ItemblueprintId) >= maxItems) { continue; } var point = _fastRandom.NextVector2IInRadius(item.SpawningRange) + new Vector2I((int)soul.Position.X, (int)soul.Position.Z); var groundSpawning = item.SpawningType == SpawningType.Ground || (item.SpawningType == SpawningType.Both && _fastRandom.NextDouble() < 0.5f); if (groundSpawning) { var cursor = _server.LandscapeManager.GetCursor(new Vector3I(point.X, AbstractChunk.ChunkSize.Y - 1, point.Y)); while (true) { var block = cursor.Read(); if (block != WorldConfiguration.CubeId.Air && block != treeBp.FoliageBlock) { break; } cursor.Move(Vector3I.Down); } cursor.Move(Vector3I.Up); if (cursor.Read() == WorldConfiguration.CubeId.Air) { if (Vector3I.Distance(cursor.GlobalPosition, (Vector3I)soul.Position) <= item.SpawningRange) { var entity = (IStaticEntity)_server.EntityFactory.CreateFromBluePrint(item.ItemblueprintId); entity.Position = cursor.GlobalPosition; var blockLinkedItem = entity as IBlockLinkedEntity; if (blockLinkedItem != null) { blockLinkedItem.LinkedCube = cursor.GlobalPosition + Vector3I.Down; } cursor.AddEntity(entity); } } } else { // lazy initialization of tree treeBlocks = treeBlocks ?? _treeLSystem.Generate(soul.TreeRndSeed, (Vector3I)soul.Position, treeBp); // find the lowest Y in our point var minY = treeBlocks.Where(b => b.WorldPosition.X == point.X && b.WorldPosition.Z == point.Y).Select(b => b.WorldPosition.Y).DefaultIfEmpty().Min(); if (minY == 0 || minY <= soul.Position.Y) { // the point is outside of tree continue; } var cursor = _server.LandscapeManager.GetCursor(new Vector3I(point.X, minY - 1, point.Y)); if (cursor.Read() == WorldConfiguration.CubeId.Air) { var entity = (IStaticEntity)_server.EntityFactory.CreateFromBluePrint(item.ItemblueprintId); entity.Position = cursor.GlobalPosition; var blockLinkedItem = entity as IBlockLinkedEntity; if (blockLinkedItem != null) { blockLinkedItem.LinkedCube = cursor.GlobalPosition + Vector3I.Down; } cursor.AddEntity(entity); } } } }