Beispiel #1
0
        //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);
            }
        }