public static void SetTargetTree(ref MyBBMemoryTarget target, Vector3D treePosition, long entityId, int treeId)
        {
            if (target == null) target = new MyBBMemoryTarget();
            target.TargetType = MyAiTargetEnum.ENVIRONMENT_ITEM;
            target.EntityId = entityId;
            target.TreeId = treeId;
            target.Position = treePosition;
		}
 public static void SetTargetCompoundBlock(ref MyBBMemoryTarget target, Vector3I blockPosition, long entityId, ushort compoundId)
 {
     if (target == null) target = new MyBBMemoryTarget();
     target.TargetType = MyAiTargetEnum.COMPOUND_BLOCK;
     target.EntityId = entityId;
     target.CompoundId = compoundId;
     target.Position = blockPosition;
 }
 public static void SetTargetVoxel(ref MyBBMemoryTarget target, Vector3I voxelPosition, long entityId)
 {
     if (target == null) target = new MyBBMemoryTarget();
     target.TargetType = MyAiTargetEnum.VOXEL;
     target.EntityId = entityId;
     target.TreeId = null;
     target.Position = new Vector3D(voxelPosition);
 }
 public static void SetTargetCube(ref MyBBMemoryTarget target, Vector3I blockPosition, long entityId)
 {
     if (target == null) target = new MyBBMemoryTarget();
     target.TargetType = MyAiTargetEnum.CUBE;
     target.EntityId = entityId;
     target.TreeId = null;
     target.Position = new Vector3D(blockPosition);
 }
 public static void SetTargetPosition(ref MyBBMemoryTarget target, Vector3D position)
 {
     if (target == null) target = new MyBBMemoryTarget();
     target.TargetType = MyAiTargetEnum.POSITION;
     target.EntityId = null;
     target.TreeId = null;
     target.Position = position;
 }
 public static void SetTargetEntity(ref MyBBMemoryTarget target, MyAiTargetEnum targetType, long entityId, Vector3D? position = null)
 {
     if (target == null) target = new MyBBMemoryTarget();
     target.TargetType = targetType;
     target.EntityId = entityId;
     target.TreeId = null;
     target.Position = position;
 }
        public static bool FindClosestPlaceAreaInSphere(BoundingSphereD sphere, string typeName, ref MyBBMemoryTarget foundTarget)
        {
            var foundAreas = new List<MyPlaceArea>();
            MyPlaceAreas.Static.GetAllAreasInSphere(sphere, foundAreas);

            var areaType = MyStringHash.GetOrCompute(typeName);

            double closestDistanceSq = sphere.Radius * sphere.Radius;
            MyPlaceArea closestArea = null;
            foreach (var area in foundAreas)
            {
                if (area.Container.Entity == null || area.AreaType != areaType)
                    continue;

                double distanceSq = area.DistanceSqToPoint(sphere.Center);
                if (distanceSq < closestDistanceSq)
                {
                    closestDistanceSq = distanceSq;
                    closestArea = area;
                }
            }

            if (closestArea == null) return false;
            MyBBMemoryTarget.SetTargetEntity(ref foundTarget, MyAiTargetEnum.ENTITY, closestArea.Container.Entity.EntityId);
            return true;
        }
 public abstract bool SetTargetFromMemory(MyBBMemoryTarget inTarget);
		public MyBehaviorTreeState HasTargetArea(ref MyBBMemoryTarget inTarget)
		{
			if (inTarget != null && inTarget.EntityId.HasValue)
			{
				MyEntity entity = null;
				if (MyEntities.TryGetEntityById(inTarget.EntityId.Value, out entity))
				{
					MyPlaceArea area = null;
					if (entity.Components.TryGet<MyPlaceArea>(out area))
					{
						return MyBehaviorTreeState.SUCCESS;
					}
				}
			}
			return MyBehaviorTreeState.FAILURE;
		}
 public MyBehaviorTreeState IsTargetValid(ref MyBBMemoryTarget inTarget)
 {
     if (inTarget != null)
     {
         if (inTarget.TargetType != MyAiTargetEnum.NO_TARGET)
             return MyBehaviorTreeState.SUCCESS;
     }
     return MyBehaviorTreeState.FAILURE;
 }
		public MyBehaviorTreeState UnsetTarget(ref MyBBMemoryTarget inTarget)
		{
			if (inTarget != null)
			{
				inTarget.TargetType = MyAiTargetEnum.NO_TARGET;
				inTarget.Position = null;
				inTarget.EntityId = null;
				inTarget.TreeId = null;
			}

			return MyBehaviorTreeState.SUCCESS;
		}
        public MyBehaviorTreeState SetTarget(ref MyBBMemoryTarget inTarget)
        {
            if (inTarget != null)
            {
                if (AiTargetBase.SetTargetFromMemory(inTarget))
                    return MyBehaviorTreeState.SUCCESS;
                else
                    return MyBehaviorTreeState.FAILURE;

            }

            return MyBehaviorTreeState.FAILURE;
        }
        public virtual bool SetTargetFromMemory(MyBBMemoryTarget memoryTarget)
        {
            if (memoryTarget.TargetType == MyAiTargetEnum.POSITION)
            {
                Debug.Assert(memoryTarget.Position.HasValue, "Position was not set correctly in memory.");
                if (!memoryTarget.Position.HasValue) return false;

                SetTargetPosition(memoryTarget.Position.Value);
                return true;
            }
            else if (memoryTarget.TargetType == MyAiTargetEnum.ENVIRONMENT_ITEM)
            {
                Debug.Assert(memoryTarget.TreeId.HasValue, "Tree id was not set correctly in memory.");
                if (!memoryTarget.TreeId.HasValue) return false;

                var tree = new MyEnvironmentItems.ItemInfo();
                tree.LocalId = memoryTarget.TreeId.Value;
                tree.Transform.Position = memoryTarget.Position.Value;
                SetTargetTree(ref tree, memoryTarget.EntityId.Value);

                return true;
            }
            else if (memoryTarget.TargetType != MyAiTargetEnum.NO_TARGET)
            {
                Debug.Assert(memoryTarget.EntityId.HasValue, "Entity id was not set correctly in memory.");
                if (!memoryTarget.EntityId.HasValue) return false;

                MyEntity entity = null;
                if (MyEntities.TryGetEntityById(memoryTarget.EntityId.Value, out entity))
                {
                    if (memoryTarget.TargetType == MyAiTargetEnum.CUBE
                        || memoryTarget.TargetType == MyAiTargetEnum.COMPOUND_BLOCK)
                    {
                        var cubeGrid = entity as MyCubeGrid;
                        var cubeBlock = cubeGrid.GetCubeBlock(memoryTarget.BlockPosition);
                        Debug.Assert(cubeBlock != null, "Invalid position for a block");

                        if (cubeBlock != null)
                        {
                            if (memoryTarget.TargetType == MyAiTargetEnum.COMPOUND_BLOCK)
                            {
                                var realBlock = (cubeBlock.FatBlock as MyCompoundCubeBlock).GetBlock(memoryTarget.CompoundId.Value);
                                Debug.Assert(realBlock != null, "Block does not exist in the compound block");
                                if (realBlock == null)
                                    return false;
                                cubeBlock = realBlock;
                                m_compoundId = memoryTarget.CompoundId;
                            }
                            SetTargetBlock(cubeBlock);
                        }
                        else
                            return false;
                    }
                    else if (memoryTarget.TargetType == MyAiTargetEnum.ENTITY)
                    {
                        if (memoryTarget.Position.HasValue && entity is MyFracturedPiece)
                            m_targetPosition = memoryTarget.Position.Value;
                        else
                            m_targetPosition = entity.PositionComp.GetPosition();

                        SetTargetEntity(entity);
                        m_targetEntity = entity;
                    }
                    else if (memoryTarget.TargetType == MyAiTargetEnum.VOXEL)
                    {
                        var voxelMap = entity as MyVoxelMap;
                        Debug.Assert(memoryTarget.Position.HasValue, "Tree id was not set correctly in memory.");
                        if (!memoryTarget.Position.HasValue) return false;

                        Debug.Assert(voxelMap != null, "Voxel map hasn't been set.");
                        if (voxelMap == null) return false;

                        SetTargetVoxel(memoryTarget.Position.Value, voxelMap);
                        m_targetEntity = voxelMap;
                    }
                    else
                    {
                        SetTargetEntity(entity);
                    }
                    return true;
                }
                else
                {
                    UnsetTarget();
                    return false;
                }
            }
            else if (memoryTarget.TargetType == MyAiTargetEnum.NO_TARGET)
            {
                UnsetTarget();
                return true;
            }
            else
            {
                Debug.Assert(false, "Unrecognized type of target!");
                UnsetTarget();
                return false;
            }
        }
        protected MyBehaviorTreeState SetTarget(bool aim, ref MyBBMemoryTarget inTarget)
        {
            if (inTarget != null)
            {
                if (AiTargetBase.SetTargetFromMemory(inTarget))
                {
                    if (aim)
                    {
                        AiTargetBase.AimAtTarget();
                    }
                    return MyBehaviorTreeState.SUCCESS;
                }
                else
                    return MyBehaviorTreeState.FAILURE;

            }
            return MyBehaviorTreeState.FAILURE;
        }
		public MyBehaviorTreeState TryReserveEntity(ref MyBBMemoryTarget inTarget, int timeMs)
		{
			MyBehaviorTreeState retStatus = MyBehaviorTreeState.FAILURE;
			if(Bot == null || Bot.Player == null)
				return MyBehaviorTreeState.FAILURE;
			
			var logic = Bot.HumanoidLogic;
			if(inTarget != null && inTarget.EntityId.HasValue && inTarget.TargetType != MyAiTargetEnum.POSITION && inTarget.TargetType != MyAiTargetEnum.NO_TARGET)
			{
				switch(logic.EntityReservationStatus)
				{
					case Logic.MyEntityReservationStatus.NONE:
						switch (inTarget.TargetType)
						{
							case MyAiTargetEnum.GRID:
							case MyAiTargetEnum.CUBE:
							case MyAiTargetEnum.CHARACTER:
							case MyAiTargetEnum.ENTITY:
								logic.EntityReservationStatus = Logic.MyEntityReservationStatus.WAITING;
								logic.ReservationEntityData = new MyAiTargetManager.ReservedEntityData() { Type = MyReservedEntityType.ENTITY,
																									   EntityId = inTarget.EntityId.Value, ReservationTimer = timeMs,
																									   ReserverId = new World.MyPlayer.PlayerId(Bot.Player.Id.SteamId, Bot.Player.Id.SerialId) };
								MyAiTargetManager.OnReservationResult += ReservationHandler;
								MyAiTargetManager.Static.RequestEntityReservation(logic.ReservationEntityData.EntityId, logic.ReservationEntityData.ReservationTimer, Bot.Player.Id.SerialId);
								break;

							case MyAiTargetEnum.ENVIRONMENT_ITEM:
								logic.EntityReservationStatus = Logic.MyEntityReservationStatus.WAITING;
								logic.ReservationEntityData = new MyAiTargetManager.ReservedEntityData() { Type = MyReservedEntityType.ENVIRONMENT_ITEM,
																									   EntityId = inTarget.EntityId.Value,
																									   LocalId = inTarget.TreeId.Value,
																									   ReservationTimer = timeMs,
																									   ReserverId = new World.MyPlayer.PlayerId(Bot.Player.Id.SteamId, Bot.Player.Id.SerialId) };
								MyAiTargetManager.OnReservationResult += ReservationHandler;
								MyAiTargetManager.Static.RequestEnvironmentItemReservation(logic.ReservationEntityData.EntityId, logic.ReservationEntityData.LocalId,
																					   logic.ReservationEntityData.ReservationTimer, Bot.Player.Id.SerialId);
								break;
							case MyAiTargetEnum.VOXEL:
								logic.EntityReservationStatus = Logic.MyEntityReservationStatus.WAITING;
								logic.ReservationEntityData = new MyAiTargetManager.ReservedEntityData() { Type = MyReservedEntityType.VOXEL,
																									   EntityId = inTarget.EntityId.Value,
																									   GridPos = inTarget.VoxelPosition,
																									   ReservationTimer = timeMs,
																									   ReserverId = new World.MyPlayer.PlayerId(Bot.Player.Id.SteamId, Bot.Player.Id.SerialId) };
								MyAiTargetManager.OnReservationResult += ReservationHandler;
								MyAiTargetManager.Static.RequestVoxelPositionReservation(logic.ReservationEntityData.EntityId, logic.ReservationEntityData.GridPos,
																					   logic.ReservationEntityData.ReservationTimer, Bot.Player.Id.SerialId);
								break;
							default:
								break;
						}
						m_reservationTimeOut = Stopwatch.GetTimestamp() + Stopwatch.Frequency * RESERVATION_WAIT_TIMEOUT_SECONDS;
						logic.EntityReservationStatus = Logic.MyEntityReservationStatus.WAITING;
						retStatus = MyBehaviorTreeState.RUNNING;
						break;

					case Logic.MyEntityReservationStatus.SUCCESS:
						retStatus = MyBehaviorTreeState.SUCCESS;
						break;

					case Logic.MyEntityReservationStatus.FAILURE:
						retStatus = MyBehaviorTreeState.FAILURE;
						break;
					case Logic.MyEntityReservationStatus.WAITING:
						if(m_reservationTimeOut < Stopwatch.GetTimestamp())
							retStatus = MyBehaviorTreeState.FAILURE;
						else
							retStatus = MyBehaviorTreeState.RUNNING;
						break;
				}
			}
			return retStatus;
		}