public override void CheckBeacons() { m_remoteTargets.Clear(); // Find beacons in range foreach (var beaconBlock in (NaniteConstructionManager.BeaconList.ToList()).Where(x => (x.Value is NaniteBeaconConstruct || x.Value is NaniteBeaconProjection))) { var item = beaconBlock.Value.BeaconBlock; if (item == null || !item.Enabled || !item.IsFunctional || !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId)) || !IsInRange(item.GetPosition(), m_maxDistance)) { continue; } GetBeaconBlocks((IMyCubeGrid)item.CubeGrid); GetBeaconBlocksRetryCounter = 0; foreach (var block in beaconBlocks) { m_constructionBlock.ScanBlocksCache.Add(new BlockTarget(block, true)); } } }
private bool AddPotentialBlock(IMySlimBlock block, bool remote = false, NaniteAreaBeacon beacon = null) { if (PotentialTargetList.Contains(block)) { return(false); } if (!remote && block.FatBlock != null && block.FatBlock is IMyTerminalBlock && block.FatBlock.OwnerId != 0 && !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(block.FatBlock.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId))) { return(false); } if (!block.IsFullIntegrity || block.HasDeformation) { if (beacon != null) { if (!m_areaTargetBlocks.ContainsKey(block)) { m_areaTargetBlocks.Add(block, beacon); } else { m_areaTargetBlocks[block] = beacon; } } PotentialTargetList.Add(block); return(true); } return(false); }
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 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)); } } }
public static bool IsValidGasConnection(MyCubeBlock factoryBlock, IMySlimBlock gasTankBlock, out IMyGasTank gasTank) { gasTank = null; try { if (gasTankBlock.FatBlock == null || gasTankBlock.FatBlock as IMyGasTank == null) { return(false); } gasTank = gasTankBlock.FatBlock as IMyGasTank; if (gasTank.GetInventory() == null || !((IMyInventory)factoryBlock.GetInventory()).IsConnectedTo(gasTank.GetInventory()) || !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(factoryBlock.GetUserRelationToOwner(gasTank.OwnerId))) { return(false); } return(true); } catch (Exception e) { Logging.Instance.WriteLine($"IsValidGasConnection exception:\n{e}."); return(false); } }
public static bool IsValidInventoryConnection(object FactoryBlockInv, object TargetBlockInv, out IMyInventory inv) { inv = null; try { MyInventory FactoryInv = (MyInventory)FactoryBlockInv; MyEntity TargetInv = null; if (TargetBlockInv is IMySlimBlock && ((IMySlimBlock)TargetBlockInv).FatBlock != null) { TargetInv = (MyEntity)((IMyEntity)(((IMySlimBlock)TargetBlockInv).FatBlock)); } else if (TargetBlockInv is MyInventory || TargetBlockInv is IMyInventory) { TargetInv = ((MyInventory)TargetBlockInv).Owner; } MyCubeBlock FactoryInvBlock = (MyCubeBlock)FactoryInv.Owner; if (TargetInv == null || FactoryInv == null || FactoryInvBlock == null || !TargetInv.HasInventory) { return(false); } MyCubeBlock InvBlock = TargetInv as MyCubeBlock; if (InvBlock == null) { return(false); } IMyProductionBlock prodblock = TargetInv as IMyProductionBlock; //assembler inv = (prodblock != null && prodblock.OutputInventory != null) ? prodblock.OutputInventory : ((IMyEntity)TargetInv).GetInventory(); if (inv == null || !InvBlock.IsFunctional || NaniteConstructionManager.NaniteBlocks.ContainsKey(TargetInv.EntityId) || TargetInv is Sandbox.ModAPI.Ingame.IMyReactor || !inv.IsConnectedTo((IMyInventory)FactoryInv) || !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(FactoryInvBlock.GetUserRelationToOwner(InvBlock.OwnerId))) { return(false); } return(true); } catch (Exception e) { Logging.Instance.WriteLine($"IsValidInventoryConnection exception:\n{e}."); return(false); } }
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}"); } }
/// <summary> /// Damage Handler: Register friendly damage /// </summary> public void AfterDamageHandlerNoDamageByBuildAndRepairSystem(object target, MyDamageInformation info) { try { if (info.Type == MyDamageType.Grind && info.Amount > 0) { var targetBlock = target as IMySlimBlock; if (targetBlock != null) { IMyEntity attackerEntity; MyAPIGateway.Entities.TryGetEntityById(info.AttackerId, out attackerEntity); var attackerId = 0L; var shipGrinder = attackerEntity as IMyShipGrinder; if (shipGrinder != null) { attackerId = shipGrinder.OwnerId; } else { var characterGrinder = attackerEntity as IMyEngineerToolBase; if (characterGrinder != null) { attackerId = characterGrinder.OwnerIdentityId; } } if (Mod.Log.ShouldLog(Logging.Level.Info)) { Mod.Log.Write(Logging.Level.Info, "BuildAndRepairSystemMod: AfterDamaged1 {0} from {1} attackerId={2} Amount={3}", Logging.BlockName(target), Logging.BlockName(attackerEntity), attackerId, info.Amount); } if (attackerId != 0) { if (Mod.Log.ShouldLog(Logging.Level.Info)) { Mod.Log.Write(Logging.Level.Info, "BuildAndRepairSystemMod: Damaged {0} from attackerId={1} Amount={2}", Logging.BlockName(target), attackerId, info.Amount); } foreach (var entry in BuildAndRepairSystems) { var relation = entry.Value.Welder.GetUserRelationToOwner(attackerId); if (Mod.Log.ShouldLog(Logging.Level.Info)) { Mod.Log.Write(Logging.Level.Info, "BuildAndRepairSystemMod: {0} Damaged Check Add FriendlyDamage {1} relation {2}", Logging.BlockName(entry.Value.Welder), Logging.BlockName(targetBlock), relation); } if (MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(relation)) { //A 'friendly' damage from grinder -> do not repair (for a while) entry.Value.FriendlyDamage[targetBlock] = MyAPIGateway.Session.ElapsedPlayTime + Settings.FriendlyDamageTimeout; if (Mod.Log.ShouldLog(Logging.Level.Info)) { Mod.Log.Write(Logging.Level.Info, "BuildAndRepairSystemMod: {0} Damaged Add FriendlyDamage {0} Timeout {1}", Logging.BlockName(entry.Value.Welder), Logging.BlockName(targetBlock), entry.Value.FriendlyDamage[targetBlock]); } } } } } } } catch (Exception e) { Mod.Log.Error("BuildAndRepairSystemMod: Exception in BeforeDamageHandlerNoDamageByBuildAndRepairSystem: Source={0}, Message={1}", e.Source, e.Message); } }
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}"); } }