//Handle staggered turret updates public override void UpdateBeforeSimulation() { Guid profilerId = SmartTurretsProfiler.Instance.Start("SyncUpdateBeforeSimulation"); int numToUpdate = (int)Math.Ceiling((SmartTurret.targetingWaitingList.Count / 60f)); for (int i = 0; i < numToUpdate; i++) { IMyEntity entity = SmartTurret.targetingWaitingList[i]; if (entity != null) { SmartTurret actionTurret = getSmartTurret(entity as IMyTerminalBlock); if (actionTurret != null) { actionTurret.needsUpdate = true; SmartTurret.targetingWaitingList.Remove(SmartTurret.targetingWaitingList[i]); } else { SmartTurret.targetingWaitingList.Remove(SmartTurret.targetingWaitingList[i]); } } else { SmartTurret.targetingWaitingList.Remove(SmartTurret.targetingWaitingList[i]); } } SmartTurretsProfiler.Instance.Stop(profilerId); }
//True if the turret can aim at its target. private static bool isInFiringArk(SmartTurret turret, Vector3D targetLocation) { IMyLargeTurretBase turretBase = turret.Entity as IMyLargeTurretBase; if (turretBase == null) { return(false); } MyLargeTurretBaseDefinition turretDefinition = (MyDefinitionManager.Static.GetCubeBlockDefinition(turretBase.BlockDefinition) as MyLargeTurretBaseDefinition); int azimuthMin = turretDefinition.MinAzimuthDegrees; int azimuthMax = turretDefinition.MaxAzimuthDegrees; int elevationMin = turretDefinition.MinElevationDegrees; int elevationMax = turretDefinition.MaxElevationDegrees; //Get turrets world rotation. Matrix3x3 turretRotation = turretBase.WorldMatrix.Rotation; //Make a Quaternion from the world rotation and invert it so we can rotate to ther way. Quaternion offset = Quaternion.CreateFromRotationMatrix(turretBase.WorldMatrix); offset.Conjugate(); offset.Normalize(); //Find the direction of the target from the turret. Vector3 dirToTarget = targetLocation - turretBase.GetPosition(); dirToTarget.Normalize(); //Rotate the dirrection of the target by the Quaternion to cancel out the turrets world rotation. dirToTarget = Vector3.Transform(dirToTarget, offset); //The targets direction is now relative to the world so we can get Azimuth and Elevation. float azimuth; float elevation; Vector3.GetAzimuthAndElevation(dirToTarget, out azimuth, out elevation); //Convert Azimuth and Elevation to deg for comparason with the turrets elevation and azimuth limits. azimuth = (float)(180 / Math.PI * azimuth); elevation = (float)(180 / Math.PI * elevation); return(azimuth >= azimuthMin && azimuth <= azimuthMax && elevation >= elevationMin && elevation <= elevationMax); }
public TargetingData(SmartTurret turret, List <IMyEntity> targets) { this.turret = turret; this.targets = targets; }
private static long?castTargetingRay(Dictionary <IMyEntity, ushort> targetTypeDictionary, SmartTurret turret) { IMyEntity turretEntity = turret.Entity; if (turretEntity == null) { return(null); } IMySlimBlock turretSlimBlock = (turretEntity as IMyCubeBlock).SlimBlock; IMyCubeGrid turretCubeGrid = turretSlimBlock.CubeGrid; Vector3D turretLocation = getTurretLocation(turretEntity); List <IMyCubeGrid> grids = new List <IMyCubeGrid>(); List <IMySlimBlock> turretGridBlockList = new List <IMySlimBlock>(); List <IMySlimBlock> targetGridBlockList = new List <IMySlimBlock>(); try { turretCubeGrid.GetBlocks(turretGridBlockList, (x) => { return(x != turretSlimBlock); }); } catch { //Harmless Enumeration error, stop targeting. return(null); } foreach (KeyValuePair <IMyEntity, ushort> pair in targetTypeDictionary) { grids.Clear(); targetGridBlockList.Clear(); IMySlimBlock targetSlimBlock = null; IMyEntity target = pair.Key; bool isTargetValid = true; IMyCubeGrid targetCubeGrid = null; Vector3D targetLocation = target.GetPosition(); LineD line = new LineD(turretLocation, targetLocation); BoundingSphereD entityCollectionZone = new BoundingSphereD(turretLocation + (turretLocation - targetLocation) / 2, Vector3D.Distance(turretLocation, targetLocation) + 1000); List <IMyEntity> entities = MyAPIGateway.Entities.GetEntitiesInSphere(ref entityCollectionZone); //Block specific setup if (target is IMyCubeBlock) { targetSlimBlock = (target as IMyCubeBlock).SlimBlock; targetCubeGrid = targetSlimBlock.CubeGrid; try { targetCubeGrid.GetBlocks(targetGridBlockList, (x) => { return(x != targetSlimBlock); }); } catch { //Harmless Enumeration error, stop targeting. return(null); } } //More setup and check voxels foreach (IMyEntity entity in entities) { if (entity is IMyCubeGrid) { IMyCubeGrid grid = entity as IMyCubeGrid; if (grid != turretCubeGrid && grid != targetCubeGrid) { grids.Add(grid); } } else if (entity is MyVoxelBase) { Vector3D?output; if ((entity as MyVoxelBase).GetIntersectionWithLine(ref line, out output)) { //log("Target: " + target.GetType().ToString() + " Failed because of intersecting voxel"); isTargetValid = false; break; } } } if (!isTargetValid) { continue; } //Relation of intersecting grids foreach (IMyCubeGrid grid in grids) { if (grid.WorldAABB.Intersects(ref line) == true) { List <IMySlimBlock> currentGridBlocks = new List <IMySlimBlock>(); try { grid.GetBlocks(currentGridBlocks); } catch { //Harmless Enumeration error, stop targeting. return(null); } MyRelationsBetweenPlayerAndBlock relation = MyRelationsBetweenPlayerAndBlock.NoOwnership; if (grid.BigOwners.Count > 0) { relation = turretSlimBlock.FatBlock.GetUserRelationToOwner(grid.BigOwners[0]); } bool throughFriendliesState = pair.Value == 35 ? false : turret.throughFriendliesStateDictionary[pair.Value]; bool throughNeutralsState = pair.Value == 35 ? false : turret.throughNeutralsStateDictionary[pair.Value]; bool throughHostilesState = pair.Value == 35 ? false : turret.throughHostilesStateDictionary[pair.Value]; if ((!throughHostilesState && relation == MyRelationsBetweenPlayerAndBlock.Enemies) || (!throughNeutralsState && (relation == MyRelationsBetweenPlayerAndBlock.Neutral || relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)) || (!throughFriendliesState && (relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare))) { foreach (IMySlimBlock slimBlock in currentGridBlocks) { BoundingBoxD collisionBox; slimBlock.GetWorldBoundingBox(out collisionBox, false); //Vector3D boxCenter = collisionBox.Center; /*float azimuth; * float elevation; * getAzimuthAndElevationRelative(collisionBox.Center - turretLocation, out azimuth, out elevation); * * float tollerence = (float)(Math.Tanh(collisionBox.Size.LengthSquared() / Vector3D.DistanceSquared(boxCenter, turretLocation)) / 2 * 0.0174533); * * if (azimuth < tollerence && azimuth > -tollerence && elevation < tollerence && elevation > -tollerence) * {*/ if (collisionBox.Intersects(ref line) == true) { slimBlock.GetWorldBoundingBox(out collisionBox, true); if (collisionBox.Intersects(ref line) == true) { //log("Target: " + target.GetType().ToString() + " Failed because of intersecting other grid"); isTargetValid = false; break; } } //} } } } } if (!isTargetValid) { continue; } //If intersecting turrets grid foreach (IMySlimBlock slimBlock in turretGridBlockList) { BoundingBoxD collisionBox; slimBlock.GetWorldBoundingBox(out collisionBox, false); //Vector3D boxCenter = collisionBox.Center; /*float azimuth; * float elevation; * getAzimuthAndElevationRelative(collisionBox.Center - turretLocation, out azimuth, out elevation); * * float tollerence = (float)(Math.Tanh(collisionBox.Size.LengthSquared() / Vector3D.DistanceSquared(boxCenter, turretLocation)) / 2 * 0.0174533); * * if (azimuth < tollerence && azimuth > -tollerence && elevation < tollerence && elevation > -tollerence) * {*/ if (collisionBox.Intersects(ref line) == true) { slimBlock.GetWorldBoundingBox(out collisionBox, true); if (collisionBox.Intersects(ref line) == true) { //log("Target: " + target.GetType().ToString() + " Failed because of intersecting own grid"); isTargetValid = false; break; } } //} } if (!isTargetValid) { continue; } //If intersecting targets grid and outside of manhatten distance if (targetSlimBlock != null) { float obstacleToleranceState = pair.Value == 35 ? 3 : turret.obstacleToleranceStateDictionary[pair.Value]; if (obstacleToleranceState < 31) { foreach (IMySlimBlock slimBlock in targetGridBlockList) { BoundingBoxD collisionBox; slimBlock.GetWorldBoundingBox(out collisionBox, false); //Vector3D boxCenter = collisionBox.Center; /*float azimuth; * float elevation; * getAzimuthAndElevationRelative(collisionBox.Center - turretLocation, out azimuth, out elevation); * * float tollerence = (float)(Math.Tanh(collisionBox.Size.LengthSquared() / Vector3D.DistanceSquared(boxCenter, turretLocation)) / 2 * 0.0174533); * * if (azimuth < tollerence && azimuth > -tollerence && elevation < tollerence && elevation > -tollerence) * {*/ if (collisionBox.Intersects(ref line) == true) { slimBlock.GetWorldBoundingBox(out collisionBox, true); if (collisionBox.Intersects(ref line) == true) { if (Vector3I.DistanceManhattan(slimBlock.Position, targetSlimBlock.Position) > obstacleToleranceState) { //log("Target: " + target.GetType().ToString() + " Failed because of intersecting target grid outside of manhattan"); isTargetValid = false; break; } } } //} } } } if (!isTargetValid) { continue; } //Target Passed! return(target.EntityId); } //All targets failed return(null); }
public SmartTurretSaveData(SmartTurret turret) { smartTargetingSwitchState = turret.smartTargetingSwitchState; targetTypesListItems = new List <ListBoxItemData>(); foreach (MyTerminalControlListBoxItem item in turret.targetTypesListItems) { targetTypesListItems.Add(item.UserData as ListBoxItemData); } rangeStateDictionaryKey = new List <ushort>(); rangeStateDictionaryValue = new List <float>(); foreach (KeyValuePair <ushort, float> item in turret.rangeStateDictionary) { rangeStateDictionaryKey.Add(item.Key); rangeStateDictionaryValue.Add(item.Value); } targetSmallGridsStateDictionaryKey = new List <ushort>(); targetSmallGridsStateDictionaryValue = new List <bool>(); foreach (KeyValuePair <ushort, bool> item in turret.targetSmallGridsStateDictionary) { targetSmallGridsStateDictionaryKey.Add(item.Key); targetSmallGridsStateDictionaryValue.Add(item.Value); } targetLargeGridsStateDictionaryKey = new List <ushort>(); targetLargeGridsStateDictionaryValue = new List <bool>(); foreach (KeyValuePair <ushort, bool> item in turret.targetLargeGridsStateDictionary) { targetLargeGridsStateDictionaryKey.Add(item.Key); targetLargeGridsStateDictionaryValue.Add(item.Value); } targetStationsStateDictionaryKey = new List <ushort>(); targetStationsStateDictionaryValue = new List <bool>(); foreach (KeyValuePair <ushort, bool> item in turret.targetStationsStateDictionary) { targetStationsStateDictionaryKey.Add(item.Key); targetStationsStateDictionaryValue.Add(item.Value); } targetNeutralsStateDictionaryKey = new List <ushort>(); targetNeutralsStateDictionaryValue = new List <bool>(); foreach (KeyValuePair <ushort, bool> item in turret.targetNeutralsStateDictionary) { targetNeutralsStateDictionaryKey.Add(item.Key); targetNeutralsStateDictionaryValue.Add(item.Value); } minimumGridSizeStateDictionaryKey = new List <ushort>(); minimumGridSizeStateDictionaryValue = new List <float>(); foreach (KeyValuePair <ushort, float> item in turret.minimumGridSizeStateDictionary) { minimumGridSizeStateDictionaryKey.Add(item.Key); minimumGridSizeStateDictionaryValue.Add(item.Value); } obstacleToleranceStateDictionaryKey = new List <ushort>(); obstacleToleranceStateDictionaryValue = new List <float>(); foreach (KeyValuePair <ushort, float> item in turret.obstacleToleranceStateDictionary) { obstacleToleranceStateDictionaryKey.Add(item.Key); obstacleToleranceStateDictionaryValue.Add(item.Value); } throughFriendliesStateDictionaryKey = new List <ushort>(); throughFriendliesStateDictionaryValue = new List <bool>(); foreach (KeyValuePair <ushort, bool> item in turret.throughFriendliesStateDictionary) { throughFriendliesStateDictionaryKey.Add(item.Key); throughFriendliesStateDictionaryValue.Add(item.Value); } throughNeutralsStateDictionaryKey = new List <ushort>(); throughNeutralsStateDictionaryValue = new List <bool>(); foreach (KeyValuePair <ushort, bool> item in turret.throughNeutralsStateDictionary) { throughNeutralsStateDictionaryKey.Add(item.Key); throughNeutralsStateDictionaryValue.Add(item.Value); } throughHostilesStateDictionaryKey = new List <ushort>(); throughHostilesStateDictionaryValue = new List <bool>(); foreach (KeyValuePair <ushort, bool> item in turret.throughHostilesStateDictionary) { throughHostilesStateDictionaryKey.Add(item.Key); throughHostilesStateDictionaryValue.Add(item.Value); } }