Exemple #1
0
        private bool IsValidCubeBlock(IMyCubeBlock block)
        {
            if (block != null)
            {
                if (block.CubeGrid.GridSizeEnum == MyCubeSize.Large)
                {
                    if (!TargetLargeShips || (block.CubeGrid.IsStatic && !TargetStations))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!TargetSmallShips)
                    {
                        return(false);
                    }
                }

                MyRelationsBetweenPlayerAndBlock relation = block.GetUserRelationToOwner(CubeBlock.OwnerId);
                if (!(relation == MyRelationsBetweenPlayerAndBlock.Enemies ||
                      TargetNeutrals && (relation == MyRelationsBetweenPlayerAndBlock.Neutral || relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                {
                    return(false);
                }

                return(true);
            }

            return(false);
        }
Exemple #2
0
        public override void CheckBeacons()
        {
            foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x.Value is NaniteBeaconProjection))
            {
                IMyCubeBlock item = (IMyCubeBlock)beaconBlock.Value.BeaconBlock;

                if (item == null || !((IMyFunctionalBlock)item).Enabled || !((IMyFunctionalBlock)item).IsFunctional ||
                    !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId)) || !IsInRange(item.GetPosition(), m_maxDistance))
                {
                    continue;
                }

                List <IMySlimBlock> beaconBlocks = new List <IMySlimBlock>();

                foreach (var grid in MyAPIGateway.GridGroups.GetGroup((IMyCubeGrid)item.CubeGrid, GridLinkTypeEnum.Physical))
                {
                    grid.GetBlocks(beaconBlocks);
                }

                foreach (var block in beaconBlocks)
                {
                    m_constructionBlock.ScanBlocksCache.Add(new BlockTarget(block));
                }
            }
        }
Exemple #3
0
        internal bool IsAreaBeaconValid(IMyCubeBlock cubeBlock)
        {
            if (cubeBlock == null || !((IMyFunctionalBlock)cubeBlock).Enabled || !((IMyFunctionalBlock)cubeBlock).IsFunctional ||
                !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(cubeBlock.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId)))
            {
                return(false);
            }

            float range = NaniteConstructionManager.Settings != null ? NaniteConstructionManager.Settings.AreaBeaconMaxDistanceFromNaniteFacility : 300f;

            foreach (var factory in m_constructionBlock.FactoryGroup)
            {
                if (IsEnabled(factory))
                {
                    if (Vector3D.Distance(cubeBlock.GetPosition(), factory.ConstructionBlock.GetPosition()) < range)
                    {
                        return(true);
                    }

                    foreach (var grid in factory.GridGroup.ToList())
                    {
                        if (cubeBlock.CubeGrid == grid)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        public override void ParallelUpdate(List <IMyCubeGrid> gridList, List <IMySlimBlock> blocks)
        {
            using (Lock.AcquireExclusiveUsing())
            {
                PotentialTargetList.Clear();
            }

            var remoteList = new HashSet <IMySlimBlock>();

            if (!IsEnabled())
            {
                return;
            }

            foreach (var block in blocks)
            {
                AddPotentialBlock(block);
            }

            foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteBeaconConstruct && Vector3D.DistanceSquared(m_constructionBlock.ConstructionBlock.GetPosition(), x.BeaconBlock.GetPosition()) < m_maxDistance * m_maxDistance))
            {
                IMyCubeBlock item = (IMyCubeBlock)beaconBlock.BeaconBlock;

                if (!((IMyFunctionalBlock)item).Enabled || !((IMyFunctionalBlock)item).IsFunctional)
                {
                    continue;
                }

                MyRelationsBetweenPlayerAndBlock relation = item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);
                if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                {
                    continue;
                }

                List <IMyCubeGrid>  beaconGridList = GridHelper.GetGridGroup((IMyCubeGrid)item.CubeGrid);
                List <IMySlimBlock> beaconBlocks   = new List <IMySlimBlock>();
                foreach (var grid in beaconGridList)
                {
                    grid.GetBlocks(beaconBlocks);
                }

                foreach (var block in beaconBlocks)
                {
                    if (AddPotentialBlock(block, true))
                    {
                        remoteList.Add(block);
                    }
                }
            }

            CheckAreaBeacons();

            using (m_remoteLock.AcquireExclusiveUsing())
            {
                m_remoteTargets = remoteList;
            }
        }
Exemple #5
0
        static public Boolean CheckOwnership(IMyCubeBlock entity, long playerId)
        {
            MyRelationsBetweenPlayerAndBlock relation = entity.GetUserRelationToOwner(playerId);

            if (relation == MyRelationsBetweenPlayerAndBlock.FactionShare || relation == MyRelationsBetweenPlayerAndBlock.Owner)
            {
                return(true);
            }

            return(false);
        }
Exemple #6
0
        static public bool IsProtected(Vector3D position, IMyCubeBlock transporterBlock)
        {
            foreach (var scrambler in ScramblerList)
            {
                var  scramblerBlock    = scrambler.CubeBlock;
                bool friendlyScrambler = transporterBlock.GetUserRelationToOwner(scramblerBlock.OwnerId).IsFriendly();

                if (scrambler.IsProtecting(position) && !friendlyScrambler)
                {
                    return(true);
                }
            }
            return(false);
        }
        private void ScanProjection(List <IMySlimBlock> blocks)
        {
            using (m_lock.AcquireExclusiveUsing())
            {
                TargetList.Clear();
                PotentialTargetList.Clear();
            }

            HashSet <IMyEntity> entities = new HashSet <IMyEntity>();

            MyAPIGateway.Entities.GetEntities(entities, x => x is IMyCubeGrid && x.Physics == null);
            foreach (var item in blocks)
            {
                CheckBlockProjection(item);
            }

            foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteBeaconProjection && Vector3D.DistanceSquared(m_constructionBlock.ConstructionBlock.GetPosition(), x.BeaconBlock.GetPosition()) < m_maxDistance * m_maxDistance))
            {
                IMyCubeBlock item = (IMyCubeBlock)beaconBlock.BeaconBlock;

                if (!((IMyFunctionalBlock)item).Enabled || !((IMyFunctionalBlock)item).IsFunctional)
                {
                    continue;
                }

                MyRelationsBetweenPlayerAndBlock relation = item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);
                if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                {
                    continue;
                }

                List <IMyCubeGrid>  beaconGridList = GridHelper.GetGridGroup((IMyCubeGrid)item.CubeGrid);
                List <IMySlimBlock> beaconBlocks   = new List <IMySlimBlock>();
                foreach (var grid in beaconGridList)
                {
                    grid.GetBlocks(beaconBlocks);
                }

                foreach (var block in beaconBlocks)
                {
                    CheckBlockProjection(block);
                }
            }

            CheckAreaBeacons();
        }
        private static Relations getRelationsTo(this IMyCubeBlock block, long playerID)
        {
            VRage.Exceptions.ThrowIf <ArgumentNullException>(block == null, "block");

            switch (block.GetUserRelationToOwner(playerID))
            {
            case MyRelationsBetweenPlayerAndBlock.Enemies:
                return(Relations.Enemy);

            case MyRelationsBetweenPlayerAndBlock.Neutral:
                return(Relations.Neutral);

            case MyRelationsBetweenPlayerAndBlock.FactionShare:
                return(Relations.Faction);

            case MyRelationsBetweenPlayerAndBlock.Owner:
                return(Relations.Owner);

            default:
                return(Relations.None);
            }
        }
Exemple #9
0
        private void runActionOnBlock(string blockName, string actionString)
        {
            //log("entered runActionOnBlock("+blockName+", "+actionString+")", "runActionOnBlock()", Logger.severity.TRACE);
            blockName    = blockName.ToLower().Replace(" ", "");
            actionString = actionString.Trim();

            List <IMySlimBlock> blocksWithName = new List <IMySlimBlock>();

            owner.myGrid.GetBlocks(blocksWithName);
            foreach (IMySlimBlock block in blocksWithName)
            {
                IMyCubeBlock fatblock = block.FatBlock;
                if (fatblock == null)
                {
                    continue;
                }

                Sandbox.Common.MyRelationsBetweenPlayerAndBlock relationship = fatblock.GetUserRelationToOwner(owner.currentRCblock.OwnerId);
                if (relationship != Sandbox.Common.MyRelationsBetweenPlayerAndBlock.Owner && relationship != Sandbox.Common.MyRelationsBetweenPlayerAndBlock.FactionShare)
                {
                    //log("failed relationship test for " + fatblock.DisplayNameText + ", result was " + relationship.ToString(), "runActionOnBlock()", Logger.severity.TRACE);
                    continue;
                }
                //log("passed relationship test for " + fatblock.DisplayNameText + ", result was " + relationship.ToString(), "runActionOnBlock()", Logger.severity.TRACE);

                //log("testing: " + fatblock.DisplayNameText, "runActionOnBlock()", Logger.severity.TRACE);
                // name test
                if (fatblock is Ingame.IMyRemoteControl)
                {
                    string nameOnly = fatblock.getNameOnly();
                    if (nameOnly == null || !nameOnly.Contains(blockName))
                    {
                        continue;
                    }
                }
                else
                {
                    if (!fatblock.DisplayNameText.looseContains(blockName))
                    {
                        //log("testing failed " + fatblock.DisplayNameText + " does not contain " + blockName, "runActionOnBlock()", Logger.severity.TRACE);
                        continue;
                    }
                    //log("testing successfull " + fatblock.DisplayNameText + " contains " + blockName, "runActionOnBlock()", Logger.severity.TRACE);
                }

                if (!(fatblock is IMyTerminalBlock))
                {
                    //log("not a terminal block: " + fatblock.DisplayNameText, "runActionOnBlock()", Logger.severity.TRACE);
                    continue;
                }
                IMyTerminalBlock terminalBlock = fatblock as IMyTerminalBlock;
                ITerminalAction  actionToRun   = terminalBlock.GetActionWithName(actionString);              // get actionToRun on every iteration so invalid blocks can be ignored
                if (actionToRun != null)
                {
                    log("running action: " + actionString + " on block: " + fatblock.DisplayNameText, "runActionOnBlock()", Logger.severity.DEBUG);
                    actionToRun.Apply(fatblock);
                }
                else
                {
                    log("could not get action: " + actionString + " for: " + fatblock.DisplayNameText, "runActionOnBlock()", Logger.severity.TRACE);
                }
            }
        }
        public override void ParallelUpdate(List <IMyCubeGrid> gridList, List <BlockTarget> gridBlocks)
        {
            try
            {
                DateTime start = DateTime.Now;

                if (!IsEnabled(m_constructionBlock))
                {
                    m_potentialMiningTargets.Clear();
                    return;
                }

                List <string> allowedMats = new List <string>();

                float range = NaniteConstructionManager.Settings != null ? NaniteConstructionManager.Settings.OreDetectorToNaniteFactoryCommunicationDistance : 300f;

                foreach (var oreDetector in NaniteConstructionManager.OreDetectors)
                {
                    if (oreDetector.Value.Block == null || m_constructionBlock.ConstructionBlock == null ||
                        !IsInRange(oreDetector.Value.Block.GetPosition(), range) || oreDetector.Value.DetectorState == NaniteOreDetector.DetectorStates.Disabled)
                    {
                        continue;
                    }

                    if (m_potentialMiningTargets.Count > 0)
                    { // Do not attempt to add more potential targets unless we're done with the current list. This will enhance performance.
                        if (oreDetector.Value.HasFilterUpgrade)
                        {
                            foreach (string mat in oreDetector.Value.OreListSelected)
                            {
                                if (!allowedMats.Contains(mat))
                                {
                                    allowedMats.Add(mat);
                                }
                            }
                        }
                        else if (!allowedMats.Contains("all"))
                        {
                            allowedMats.Add("all");
                        }

                        break;
                    }

                    IMyCubeBlock item = oreDetector.Value.Block;

                    if (!MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId)))
                    {
                        continue;
                    }

                    var materialList = oreDetector.Value.DepositGroup.SelectMany((x) => x.Value.Materials.MiningMaterials());
                    if (materialList.Count() == 0 && oreDetector.Value.minedPositions.Count > 0)
                    {
                        Logging.Instance.WriteLine("[Mining] Clearing deposit groups due to no new minable targets.");
                        oreDetector.Value.ClearMinedPositions();
                        oreDetector.Value.DepositGroup.Clear();
                        continue;
                    }

                    foreach (var material in materialList.ToList())
                    {
                        try
                        {
                            int             minimumAmount   = NaniteConstructionManager.Settings != null ? NaniteConstructionManager.Settings.MiningTargetsScannedPerSecond : 100;
                            int             amountToProcess = Math.Min(material.WorldPosition.Count, minimumAmount * 5);
                            List <Vector3D> removeList      = new List <Vector3D>();
                            for (int i = 0; i < amountToProcess; i++)
                            {
                                try
                                { // material iterations
                                    bool     alreadyMined = false;
                                    Vector3D removePos    = Vector3D.Zero;
                                    foreach (var minedPos in m_globalPositionList.ToList())
                                    {
                                        if (material.WorldPosition[i] == minedPos)
                                        {
                                            alreadyMined = true;
                                            removeList.Add(material.WorldPosition[i]);
                                            removePos = minedPos;
                                            Logging.Instance.WriteLine($"[Mining] Found an already mined position {minedPos}", 2);
                                            break;
                                        }
                                    }

                                    if (alreadyMined)
                                    {
                                        MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                                                  { m_globalPositionList.Remove(removePos); });
                                        continue;
                                    }

                                    NaniteMiningItem target = new NaniteMiningItem();
                                    target.Position      = material.WorldPosition[i];
                                    target.VoxelPosition = material.VoxelPosition[i];
                                    target.Definition    = material.Definition;
                                    target.VoxelMaterial = material.Material;
                                    target.VoxelId       = material.EntityId;
                                    target.Amount        = 1f;
                                    target.OreDetectorId = ((MyEntity)item).EntityId;

                                    if (voxelEntities.ContainsKey(material.EntityId))
                                    {
                                        PrepareTarget(voxelEntities[material.EntityId], target);
                                        MyAPIGateway.Parallel.Sleep(1);
                                    }
                                    else
                                    {
                                        MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                                                  { TryAddNewVoxelEntity(material.EntityId, oreDetector.Value); });

                                        break;
                                    }
                                }
                                catch (ArgumentException e) when(e.ToString().ToLower().Contains("destination array is not long enough"))
                                {
                                    Logging.Instance.WriteLine("NaniteMiningTargets.ParallelUpdate: An ArgumentException "
                                                               + "('Destination array is not long enough') was caught. This is probably harmless and can be ignored.", 1);
                                    Logging.Instance.WriteLine($"{e}", 2);
                                    continue;
                                }
                                catch (Exception e)
                                {
                                    Logging.Instance.WriteLine($"Exception during NaniteMiningTargets.ParallelUpdate material iterations:\n{e}");
                                    continue;
                                }
                            }

                            foreach (Vector3D pos in removeList)
                            {
                                material.WorldPosition.Remove(pos);
                            }
                        }
                        catch (Exception e) when(e.ToString().Contains("ArgumentOutOfRangeException"))
                        { // because Keen thinks we shouldn't have access to this exception^ ...
                            Logging.Instance.WriteLine("Caught an ArgumentOutOfRangeException while processing mining targets. This is probably harmless and can be ignored.");
                        }
                    }

                    if (m_oldMinedPositionsCount == m_minedPositionsCount && m_minedPositionsCount > 0)
                    {
                        if (m_scannertimeout++ > 20)
                        {
                            m_scannertimeout = 0;
                            oreDetector.Value.DepositGroup.Clear(); //we've mined all the scanned stuff. Try a rescan.
                            Logging.Instance.WriteLine("[Mining] Clearing deposit groups due to mining target timeout.", 1);
                            m_minedPositionsCount = 0;
                        }
                    }
                    else
                    {
                        m_oldMinedPositionsCount = m_minedPositionsCount;
                        m_scannertimeout         = 0;
                    }
                }

                if (allowedMats.Count > 0 && !allowedMats.Contains("all"))
                {
                    List <NaniteMiningItem> removeList = new List <NaniteMiningItem>();
                    foreach (var target in m_potentialMiningTargets)
                    {
                        if (allowedMats.Where(x => x.ToLower() == target.Definition.MinedOre.ToLower()).FirstOrDefault() == null)
                        {
                            removeList.Add(target);
                        }

                        MyAPIGateway.Parallel.Sleep(1);
                    }

                    foreach (var target in removeList)
                    {
                        m_potentialMiningTargets.Remove(target);
                    }
                }

                while (finalAddList.Count > 0)
                {
                    NaniteMiningItem miningTarget;
                    if (finalAddList.TryTake(out miningTarget))
                    {
                        m_potentialMiningTargets.Add(miningTarget);
                    }
                }

                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                          { PotentialTargetListCount = m_potentialMiningTargets.Count; });
            }
            catch (ArgumentException e)
            {
                Logging.Instance.WriteLine("NaniteMiningTargets.ParallelUpdate: An ArgumentException "
                                           + "('Destination array is not long enough') was caught. This is probably harmless and can be ignored.");
                Logging.Instance.WriteLine($"{e}", 2);
            }
            catch (Exception e)
            { Logging.Instance.WriteLine($"{e}"); }
        }
Exemple #11
0
        public override void ParallelUpdate(List <IMyCubeGrid> gridList, List <IMySlimBlock> gridBlocks)
        {
            using (Lock.AcquireExclusiveUsing())
                PotentialTargetList.Clear();

            DateTime      start        = DateTime.Now;
            List <object> finalAddList = new List <object>();
            int           listCount    = 0;

            foreach (var miningBlock in NaniteConstructionManager.MiningList.Where(x => x.IsWorking && Vector3D.DistanceSquared(m_constructionBlock.ConstructionBlock.GetPosition(), x.MiningBlock.GetPosition()) < m_maxDistance * m_maxDistance).OrderBy(x => rnd.Next(100)))
            {
                IMyCubeBlock item = (IMyCubeBlock)miningBlock.MiningBlock;
                MyRelationsBetweenPlayerAndBlock relation = item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);
                if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                {
                    continue;
                }

                if (!((IMyFunctionalBlock)item).Enabled)
                {
                    continue;
                }

                if (miningBlock.OreList == null || miningBlock.OreList.Count < 1)
                {
                    continue;
                }

                int sum = miningBlock.OreList.Sum(x => x.Value.Count);
                Dictionary <MyVoxelMaterialDefinition, List <NaniteMiningItem> > lookup = null;
                using (miningBlock.Lock.AcquireExclusiveUsing())
                {
                    lookup = miningBlock.OreList.ToDictionary(x => x.Key, x => x.Value);
                }

                List <object> addList = new List <object>();
                int           count   = 0;
                int           pos     = 0;

                while (true)
                {
                    var group = lookup.ElementAt(count % miningBlock.OreList.Count);
                    if (pos < group.Value.Count)
                    {
                        addList.Insert(0, group.Value[pos]);
                    }

                    count++;
                    if (count % miningBlock.OreList.Count == 0)
                    {
                        pos++;
                    }

                    if (count >= 1000)
                    {
                        break;
                    }

                    if (count >= sum)
                    {
                        break;
                    }
                }

                DistributeList(addList, finalAddList, listCount);
                listCount++;

                if (listCount > 5)
                {
                    break;
                }
            }

            var listToAdd = finalAddList.Take(1000).ToList();

            listToAdd.Reverse();
            using (Lock.AcquireExclusiveUsing())
            {
                PotentialTargetList.AddRange(listToAdd);
            }

            //Logging.Instance.WriteLine(string.Format("ParallelUpdate() took {0} ms", (DateTime.Now - start).TotalMilliseconds));
        }
        public override void ParallelUpdate(List <IMyCubeGrid> NaniteGridGroup, List <BlockTarget> gridBlocks)
        {
            try
            {
                // Add
                foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x.Value is NaniteBeaconDeconstruct))
                {
                    IMyCubeBlock item = (IMyCubeBlock)beaconBlock.Value.BeaconBlock;

                    if (item == null ||
                        item.CubeGrid == null ||
                        !((IMyFunctionalBlock)item).Enabled ||
                        !((IMyFunctionalBlock)item).IsFunctional ||
                        NaniteGridGroup.Contains(item.CubeGrid) ||
                        !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId)) ||
                        m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(item.CubeGrid)) != null ||
                        !IsInRange(item.GetPosition(), m_maxDistance)
                        )
                    {
                        continue;
                    }

                    NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(item.CubeGrid);

                    CreateGridStack(NaniteGridGroup, deconstruct, (MyCubeGrid)item.CubeGrid, (MyCubeBlock)item);
                    m_validBeaconedGrids.Add(deconstruct);

                    Logging.Instance.WriteLine($"[Deconstruction] Grid {item.CubeGrid.CustomName} queued for deconstruction", 1);

                    foreach (var slimBlock in deconstruct.RemoveList)
                    {
                        if (slimBlock != null)
                        {
                            PotentialTargetList.Add(slimBlock);
                        }
                    }

                    deconstruct.RemoveList.Clear();
                }

                CheckAreaBeacons(NaniteGridGroup);

                if (PotentialTargetList.Count > 0)
                {
                    foreach (IMySlimBlock item in PotentialTargetList.ToList())
                    {
                        if (item == null || item.CubeGrid == null || item.CubeGrid.Closed || item.IsDestroyed || item.IsFullyDismounted ||
                            (item.FatBlock != null && item.FatBlock.Closed) ||
                            EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, item) > m_maxDistance)
                        {
                            PotentialTargetList.Remove(item);
                        }
                    }
                }
                else if (TargetList.Count == 0 && PotentialTargetList.Count == 0)
                {
                    m_validBeaconedGrids.Clear();
                }
            }
            catch (Exception e)
            { Logging.Instance.WriteLine($"Exception in NaniteDeconstructionTargets.ParallelUpdate:\n{e}"); }
        }
		/// <summary>
		/// Different from the others because share mode matters.
		/// </summary>
		public static bool canControlBlock(this IMyCubeBlock block, IMyCubeBlock target)
		{
			switch (target.GetUserRelationToOwner(block.OwnerId))
			{
				case MyRelationsBetweenPlayerAndBlock.Enemies:
				case MyRelationsBetweenPlayerAndBlock.Neutral:
					return false;
				case MyRelationsBetweenPlayerAndBlock.FactionShare:
				case MyRelationsBetweenPlayerAndBlock.Owner:
					return true;
				case MyRelationsBetweenPlayerAndBlock.NoOwnership:
				default:
					return target.OwnerId == 0;
			}
		}
        //MAIN TARGETING. The main targeting method, only to be run on other threads because this is laggy af.
        public static void validateTargetsThread(WorkData tempData)
        {
            Guid profilerId = SmartTurretsProfiler.Instance.Start("validateTargetsThread");

            try
            {
                TargetingData data           = (TargetingData)tempData;
                Vector3D      turretLocation = data.turret.Entity.GetPosition();
                Dictionary <IMyEntity, ushort> targetTypeDictionary = getTargetTypeDictionary(data.targets);

                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 0: " + targetTypeDictionary.Count.ToString() + " : " + getTypes(targetTypeDictionary));
                //Eliminate targets that are not functional.
                for (int i = targetTypeDictionary.Count - 1; i >= 0; i--)
                {
                    ushort curretType = targetTypeDictionary.ElementAt(i).Value;

                    //Ignore non-cube types.
                    if (curretType != 31 && curretType != 32 && curretType != 33)
                    {
                        if (((IMyCubeBlock)targetTypeDictionary.ElementAt(i).Key).IsFunctional == false)
                        {
                            targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                        }
                    }
                }

                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 1: " + targetTypeDictionary.Count.ToString() + " : " + getTypes(targetTypeDictionary));
                //Eliminate targets that are disabled in targeting settings.
                for (int i = targetTypeDictionary.Count - 1; i >= 0; i--)
                {
                    ushort CurretType = targetTypeDictionary.ElementAt(i).Value;
                    if (CurretType != 35)
                    {
                        MyTerminalControlListBoxItem typeItem = data.turret.targetTypesListItems.Find((x) => { return((x.UserData as ListBoxItemData).id == CurretType); });
                        if ((typeItem.UserData as ListBoxItemData).enabledState == false)
                        {
                            targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                        }
                    }
                }

                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 2: " + targetTypeDictionary.Count.ToString() + " : " + getTypes(targetTypeDictionary));
                //Eliminate targets that are friendly or are neutral should that be set appropriatly.
                for (int i = targetTypeDictionary.Count - 1; i >= 0; i--)
                {
                    ushort curretType = targetTypeDictionary.ElementAt(i).Value;

                    var cubeEntity = (data.turret.Entity as IMyCubeBlock);
                    if (cubeEntity != null)
                    {
                        if (curretType != 31 && curretType != 32 && curretType != 33)
                        {
                            if (curretType != 13)
                            {
                                //Check relation of blocks with ownership
                                IMyCubeBlock cubeBlock = (IMyCubeBlock)targetTypeDictionary.ElementAt(i).Key;
                                MyRelationsBetweenPlayerAndBlock relation = cubeBlock.GetUserRelationToOwner(cubeEntity.OwnerId);

                                if ((relation != MyRelationsBetweenPlayerAndBlock.Enemies && relation != MyRelationsBetweenPlayerAndBlock.Neutral) || ((relation == MyRelationsBetweenPlayerAndBlock.Neutral || relation == MyRelationsBetweenPlayerAndBlock.NoOwnership) && data.turret.targetNeutralsStateDictionary[targetTypeDictionary.ElementAt(i).Value] == false))
                                {
                                    targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                                }
                            }
                            else
                            {
                                //Check relation of blocks that cannot have ownership based on grid ownership
                                IMyCubeGrid cubeGrid = (targetTypeDictionary.ElementAt(i).Key as IMyCubeBlock).CubeGrid;
                                MyRelationsBetweenPlayerAndBlock relation = MyRelationsBetweenPlayerAndBlock.NoOwnership;

                                if (cubeGrid.BigOwners.Count > 0)
                                {
                                    relation = cubeEntity.GetUserRelationToOwner(cubeGrid.BigOwners[0]);
                                }

                                if ((relation != MyRelationsBetweenPlayerAndBlock.Enemies && relation != MyRelationsBetweenPlayerAndBlock.Neutral) || ((relation == MyRelationsBetweenPlayerAndBlock.Neutral || relation == MyRelationsBetweenPlayerAndBlock.NoOwnership) && data.turret.targetNeutralsStateDictionary[targetTypeDictionary.ElementAt(i).Value] == false))
                                {
                                    targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                                }
                            }
                        }
                        else if (curretType == 31) //Check relation of players
                        {
                            if (cubeEntity != null)
                            {
                                List <IMyPlayer> Players = new List <IMyPlayer>();
                                MyAPIGateway.Players.GetPlayers(Players, (x) => { return(x.Character.EntityId == targetTypeDictionary.ElementAt(i).Key.EntityId); });

                                //IDK why this uses MyRelationsBetweenPlayerAndBlock when MyRelationsBetweenPlayers is a thing... KEEN!
                                MyRelationsBetweenPlayerAndBlock relation = Players.First().GetRelationTo(cubeEntity.OwnerId);
                                if ((relation != MyRelationsBetweenPlayerAndBlock.Enemies && relation != MyRelationsBetweenPlayerAndBlock.Neutral) || ((relation == MyRelationsBetweenPlayerAndBlock.Neutral || relation == MyRelationsBetweenPlayerAndBlock.NoOwnership) && data.turret.targetNeutralsStateDictionary[targetTypeDictionary.ElementAt(i).Value] == false))
                                {
                                    targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                                }
                            }
                        }
                    }

                    //Ignore non-cube types.
                }

                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 3: " + targetTypeDictionary.Count.ToString() + " : " + getTypes(targetTypeDictionary));
                //Eliminate targets that are out of range.
                for (int i = targetTypeDictionary.Count - 1; i >= 0; i--)
                {
                    ushort CurretType = targetTypeDictionary.ElementAt(i).Value;

                    if (CurretType != 35)
                    {
                        if (checkTargetOutOfRange(turretLocation, data.turret.rangeStateDictionary[CurretType], targetTypeDictionary.ElementAt(i).Key.GetPosition()))
                        {
                            targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                        }
                    }
                    else
                    {
                        var terminalEntity = data.turret.Entity as IMyTerminalBlock;
                        if (terminalEntity != null)
                        {
                            if (checkTargetOutOfRange(turretLocation, getTurretMaxRange(terminalEntity), targetTypeDictionary.ElementAt(i).Key.GetPosition()))
                            {
                                targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                            }
                        }
                    }
                }

                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 4: " + targetTypeDictionary.Count.ToString() + " : " + getTypes(targetTypeDictionary));
                //Eliminate targets that are on the wrong type of grid.
                for (int i = targetTypeDictionary.Count - 1; i >= 0; i--)
                {
                    ushort curretType = targetTypeDictionary.ElementAt(i).Value;

                    //Ignore non-cube types and decoys.
                    if (curretType != 31 && curretType != 32 && curretType != 33 && curretType != 35)
                    {
                        IMyCubeGrid grid          = ((IMyCubeBlock)targetTypeDictionary.ElementAt(i).Key).CubeGrid;
                        bool        targetLarge   = data.turret.targetLargeGridsStateDictionary[targetTypeDictionary.ElementAt(i).Value];
                        bool        targetSmall   = data.turret.targetSmallGridsStateDictionary[targetTypeDictionary.ElementAt(i).Value];
                        bool        targetStation = data.turret.targetStationsStateDictionary[targetTypeDictionary.ElementAt(i).Value];

                        if ((grid.GridSizeEnum == MyCubeSize.Large && targetLarge == false) || (grid.GridSizeEnum == MyCubeSize.Small && targetSmall == false) || (grid.IsStatic == true && targetStation == false))
                        {
                            targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                        }
                    }
                }

                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 5: " + targetTypeDictionary.Count.ToString() + " : " + getTypes(targetTypeDictionary));
                //Eliminate targets that are on grids that are too small.
                for (int i = targetTypeDictionary.Count - 1; i >= 0; i--)
                {
                    ushort curretType = targetTypeDictionary.ElementAt(i).Value;

                    //Ignore non-cube types and decoys.
                    if (curretType != 31 && curretType != 32 && curretType != 33 && curretType != 35)
                    {
                        List <IMySlimBlock> gridBlocks = new List <IMySlimBlock>();
                        try
                        {
                            ((IMyCubeBlock)targetTypeDictionary.ElementAt(i).Key).CubeGrid.GetBlocks(gridBlocks);
                        }
                        catch
                        {
                            //Problematic Enumeration error, stop targeting.
                            data.validTargetID = null;
                            return;
                        }

                        //MinGridSize
                        if (gridBlocks.Count < data.turret.minimumGridSizeStateDictionary[targetTypeDictionary.ElementAt(i).Value])
                        {
                            targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                        }
                    }
                }

                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 6: " + targetTypeDictionary.Count.ToString() + " : " + getTypes(targetTypeDictionary));
                //Eliminate targets that are out of the turrets firing ark.

                for (int i = targetTypeDictionary.Count - 1; i >= 0; i--)
                {
                    if (isInFiringArk(data.turret, targetTypeDictionary.ElementAt(i).Key.GetPosition()) == false)
                    {
                        targetTypeDictionary.Remove(targetTypeDictionary.ElementAt(i).Key);
                    }
                }


                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 7: " + targetTypeDictionary.Count.ToString() + " : " + getTypes(targetTypeDictionary));
                //Sort targets by priority and distance.
                List <IMyEntity> tempTargets = targetTypeDictionary.Keys.ToList();
                if (data.turret.Entity != null)
                {
                    tempTargets.Sort(new SortByTargetingPriorityAndDistance(data.turret.Entity.GetPosition(), targetTypeDictionary, data.turret.targetTypesListItems));
                }


                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 8");
                //Update TargetTypeDictionary with new order.
                targetTypeDictionary = getTargetTypeDictionary(tempTargets);

                //log("Turret: " + data.turret.Entity.EntityId.ToString() + " 9: " + targetTypeDictionary.Count.ToString() + " : " + getTypes(targetTypeDictionary));
                //Start shooting rays.
                //try
                //{
                data.validTargetID = castTargetingRay(targetTypeDictionary, data.turret);
                //}
                //catch (Exception err)
                //{
                //    log(err.Message);
                //    log(err.StackTrace);
                //}
            }
            catch (Exception e)
            {
                log(e.Message);
                log(e.StackTrace);
            }

            SmartTurretsProfiler.Instance.Stop(profilerId);
        }
Exemple #15
0
        public static Boolean CheckOwnership(IMyCubeBlock entity, long playerId)
        {
            MyRelationsBetweenPlayerAndBlock relation = entity.GetUserRelationToOwner(playerId);

            if (relation == MyRelationsBetweenPlayerAndBlock.FactionShare || relation == MyRelationsBetweenPlayerAndBlock.Owner)
                return true;

            return false;
        }
        private void CheckAreaBeacons()
        {
            foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteAreaBeacon))
            {
                IMyCubeBlock cubeBlock = (IMyCubeBlock)beaconBlock.BeaconBlock;

                if (!((IMyFunctionalBlock)cubeBlock).Enabled || !((IMyFunctionalBlock)cubeBlock).IsFunctional)
                {
                    continue;
                }

                MyRelationsBetweenPlayerAndBlock relation = cubeBlock.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);
                if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                {
                    continue;
                }

                var item = beaconBlock as NaniteAreaBeacon;
                if (!item.Settings.AllowDeconstruction)
                {
                    continue;
                }

                HashSet <IMyEntity> entities = new HashSet <IMyEntity>();
                MyAPIGateway.Entities.GetEntities(entities);
                foreach (var entity in entities)
                {
                    var grid = entity as IMyCubeGrid;
                    if (grid == null)
                    {
                        continue;
                    }

                    if (grid.Physics == null)
                    {
                        continue;
                    }

                    if (grid.Physics.AngularVelocity.Length() != 0f || grid.Physics.LinearVelocity.Length() != 0f)
                    {
                        continue;
                    }

                    if (m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(grid)) != null)
                    {
                        continue;
                    }

                    if (GridHelper.GetGridGroup(grid).Contains(cubeBlock.CubeGrid))
                    {
                        continue;
                    }

                    if ((grid.GetPosition() - cubeBlock.GetPosition()).LengthSquared() < m_maxDistance * m_maxDistance)
                    {
                        if (item.IsInsideBox(grid.WorldAABB, false))
                        {
                            NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(grid);
                            m_validBeaconedGrids.Add(deconstruct);
                            CreateGridStack(deconstruct, (MyCubeGrid)grid, null);
                            if (!m_areaTargetBlocks.ContainsKey(grid))
                            {
                                m_areaTargetBlocks.Add(grid, item);
                            }
                            else
                            {
                                m_areaTargetBlocks[grid] = item;
                            }

                            foreach (var block in deconstruct.RemoveList)
                            {
                                if (!PotentialTargetList.Contains(block))
                                {
                                    PotentialTargetList.Add(block);
                                }
                            }
                        }
                    }
                }
            }
        }
        public override void ParallelUpdate(List <IMyCubeGrid> gridList, List <IMySlimBlock> gridBlocks)
        {
            try
            {
                if (!IsEnabled())
                {
                    PotentialTargetList.Clear();
                    return;
                }

                // Add
                foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteBeaconDeconstruct && Vector3D.DistanceSquared(m_constructionBlock.ConstructionBlock.GetPosition(), x.BeaconBlock.GetPosition()) < m_maxDistance * m_maxDistance))
                {
                    IMyCubeBlock item = (IMyCubeBlock)beaconBlock.BeaconBlock;

                    if (!((IMyFunctionalBlock)item).Enabled || !((IMyFunctionalBlock)item).IsFunctional)
                    {
                        continue;
                    }

                    if (gridList.Contains(item.CubeGrid))
                    {
                        continue;
                    }

                    MyRelationsBetweenPlayerAndBlock relation = item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);
                    if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                    {
                        continue;
                    }

                    if (m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(item.CubeGrid)) != null)
                    {
                        continue;
                    }

                    NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(item.CubeGrid);
                    m_validBeaconedGrids.Add(deconstruct);
                    CreateGridStack(deconstruct, (MyCubeGrid)item.CubeGrid, (MyCubeBlock)item);

                    using (Lock.AcquireExclusiveUsing())
                    {
                        foreach (var slimBlock in deconstruct.RemoveList)
                        {
                            if (!PotentialTargetList.Contains(slimBlock))
                            {
                                PotentialTargetList.Add(slimBlock);
                            }
                        }
                    }

                    deconstruct.RemoveList.Clear();
                }

                CheckAreaBeacons();

                if (PotentialTargetList.Count > 0)
                {
                    using (Lock.AcquireExclusiveUsing())
                    {
                        foreach (IMySlimBlock item in PotentialTargetList.ToList())
                        {
                            if (item.CubeGrid.Closed || item.IsDestroyed || item.IsFullyDismounted || (item.FatBlock != null && item.FatBlock.Closed))
                            {
                                PotentialTargetList.Remove(item);
                            }

                            if (EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, item) > m_maxDistance)
                            {
                                PotentialTargetList.Remove(item);
                            }
                        }

                        //m_potentialTargetList = m_potentialTargetList.OrderBy(x => GetBlockConnections((IMySlimBlock)(x))).ToList();
                    }
                }
                else if (TargetList.Count == 0 && PotentialTargetList.Count == 0)
                {
                    m_validBeaconedGrids.Clear();
                }
            }
            catch (Exception ex)
            {
                Logging.Instance.WriteLine(string.Format("Parallel Erorr: {0}", ex.ToString()));
            }
        }