Example #1
0
        internal static bool GetClosestHitableBlockOfType(ConcurrentCachingList <MyCubeBlock> cubes, GridAi ai, Target target, Vector3D currentPos, Vector3D targetLinVel, Vector3D targetAccel, WeaponSystem system, Weapon w = null, bool checkPower = true)
        {
            var minValue  = double.MaxValue;
            var minValue0 = double.MaxValue;
            var minValue1 = double.MaxValue;
            var minValue2 = double.MaxValue;
            var minValue3 = double.MaxValue;

            MyCubeBlock newEntity   = null;
            MyCubeBlock newEntity0  = null;
            MyCubeBlock newEntity1  = null;
            MyCubeBlock newEntity2  = null;
            MyCubeBlock newEntity3  = null;
            var         bestCubePos = Vector3D.Zero;
            var         top5Count   = target.Top5.Count;
            var         testPos     = currentPos;
            var         top5        = target.Top5;
            IHitInfo    hitInfo     = null;
            var         notSelfHit  = false;

            for (int i = 0; i < cubes.Count + top5Count; i++)
            {
                ai.Session.BlockChecks++;
                var index = i < top5Count ? i : i - top5Count;
                var cube  = i < top5Count ? top5[index] : cubes[index];

                var grid = cube.CubeGrid;
                if (grid?.Physics == null || !grid.Physics.Enabled || grid.PositionComp == null)
                {
                    continue;
                }

                if (cube.MarkedForClose || checkPower && !cube.IsWorking || !(cube is IMyTerminalBlock) || cube == newEntity || cube == newEntity0 || cube == newEntity1 || cube == newEntity2 || cube == newEntity3)
                {
                    continue;
                }
                var cubePos = grid.GridIntegerToWorld(cube.Position);
                var range   = cubePos - testPos;
                var test    = (range.X * range.X) + (range.Y * range.Y) + (range.Z * range.Z);
                if (test < minValue3)
                {
                    IHitInfo hit      = null;
                    var      best     = test < minValue;
                    var      bestTest = false;
                    if (best)
                    {
                        if (w != null && !(!w.IsTurret && w.ActiveAmmoDef.AmmoDef.Trajectory.Smarts.OverideTarget))
                        {
                            ai.Session.CanShoot++;
                            var castRay = false;

                            Vector3D predictedPos;
                            Vector3D?hitPos;
                            if (Weapon.CanShootTarget(w, cubePos, targetLinVel, targetAccel, out predictedPos))
                            {
                                castRay = !w.HitOther || !GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref testPos, ref cubePos, out hitPos, w.Comp.MyCube, w.Comp.Ai);
                            }

                            if (castRay)
                            {
                                ai.Session.ClosestRayCasts++;
                                bestTest = MyAPIGateway.Physics.CastRay(testPos, cubePos, out hit, 15, true) && hit?.HitEntity == cube.CubeGrid;

                                if (hit == null && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf()) || (hit.HitEntity != ai.MyGrid))
                                {
                                    notSelfHit = true;
                                }
                            }
                        }
                        else
                        {
                            bestTest = true;
                        }
                    }
                    if (best && bestTest)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = minValue;
                        newEntity0 = newEntity;
                        minValue   = test;

                        newEntity   = cube;
                        bestCubePos = cubePos;
                        hitInfo     = hit;
                    }
                    else if (test < minValue0)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = test;

                        newEntity0 = cube;
                    }
                    else if (test < minValue1)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = test;

                        newEntity1 = cube;
                    }
                    else if (test < minValue2)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = test;

                        newEntity2 = cube;
                    }
                    else
                    {
                        minValue3  = test;
                        newEntity3 = cube;
                    }
                }
            }
            top5.Clear();
            if (newEntity != null && hitInfo != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist * (1 - hitInfo.Fraction);
                var origDist  = rayDist * hitInfo.Fraction;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, hitInfo.Position, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else if (newEntity != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist;
                var origDist  = rayDist;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, bestCubePos, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else
            {
                target.Reset(ai.Session.Tick, Target.States.NoTargetsSeen, w == null);
            }

            if (newEntity0 != null)
            {
                top5.Add(newEntity0);
            }
            if (newEntity1 != null)
            {
                top5.Add(newEntity1);
            }
            if (newEntity2 != null)
            {
                top5.Add(newEntity2);
            }
            if (newEntity3 != null)
            {
                top5.Add(newEntity3);
            }

            if (!notSelfHit && w != null)
            {
                w.HitOther = true;
            }

            return(hitInfo != null);
        }
Example #2
0
        internal static void AcquireProjectile(Weapon w, out TargetType targetType)
        {
            var ai        = w.Comp.Ai;
            var s         = w.System;
            var physics   = s.Session.Physics;
            var target    = w.NewTarget;
            var weaponPos = w.MyPivotPos;

            var collection   = ai.GetProCache();
            var numOfTargets = collection.Count;
            var lockedOnly   = w.System.Values.Targeting.LockedSmartOnly;
            var smartOnly    = w.System.Values.Targeting.IgnoreDumbProjectiles;

            if (s.ClosestFirst)
            {
                int length = collection.Count;
                for (int h = length / 2; h > 0; h /= 2)
                {
                    for (int i = h; i < length; i += 1)
                    {
                        var    tempValue = collection[i];
                        double temp;
                        Vector3D.DistanceSquared(ref collection[i].Position, ref weaponPos, out temp);

                        int j;
                        for (j = i; j >= h && Vector3D.DistanceSquared(collection[j - h].Position, weaponPos) > temp; j -= h)
                        {
                            collection[j] = collection[j - h];
                        }

                        collection[j] = tempValue;
                    }
                }
            }

            var numToRandomize = s.ClosestFirst ? w.System.Values.Targeting.TopTargets : numOfTargets;
            var deck           = GetDeck(ref target.TargetDeck, ref target.TargetPrevDeckLen, 0, numOfTargets, numToRandomize, w.TargetData.WeaponRandom, Acquire);

            for (int x = 0; x < numOfTargets; x++)
            {
                var card = deck[x];
                var lp   = collection[card];
                var cube = lp.Info.Target.Entity as MyCubeBlock;
                if (smartOnly && !lp.SmartsOn || lockedOnly && (!lp.SmartsOn || cube != null && cube.CubeGrid.IsSameConstructAs(w.Comp.Ai.MyGrid)) || lp.MaxSpeed > s.MaxTargetSpeed || lp.MaxSpeed <= 0 || lp.State != Projectile.ProjectileState.Alive || Vector3D.DistanceSquared(lp.Position, w.MyPivotPos) > w.MaxTargetDistanceSqr || Vector3D.DistanceSquared(lp.Position, w.MyPivotPos) < w.MinTargetDistanceSqr)
                {
                    continue;
                }

                Vector3D predictedPos;
                if (Weapon.CanShootTarget(w, ref lp.Position, lp.Velocity, lp.AccelVelocity, out predictedPos))
                {
                    var needsCast = false;
                    for (int i = 0; i < ai.Obstructions.Count; i++)
                    {
                        var ent       = ai.Obstructions[i];
                        var obsSphere = ent.PositionComp.WorldVolume;

                        var dir  = lp.Position - weaponPos;
                        var beam = new RayD(ref weaponPos, ref dir);

                        if (beam.Intersects(obsSphere) != null)
                        {
                            var transform = ent.PositionComp.WorldMatrixRef;
                            var box       = ent.PositionComp.LocalAABB;
                            var obb       = new MyOrientedBoundingBoxD(box, transform);
                            if (obb.Intersects(ref beam) != null)
                            {
                                needsCast = true;
                                break;
                            }
                        }
                    }

                    if (needsCast)
                    {
                        IHitInfo hitInfo;
                        physics.CastRay(weaponPos, lp.Position, out hitInfo, 15);
                        if (hitInfo?.HitEntity == null && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf()))
                        {
                            double hitDist;
                            Vector3D.Distance(ref weaponPos, ref lp.Position, out hitDist);
                            var        shortDist = hitDist;
                            var        origDist  = hitDist;
                            const long topEntId  = long.MaxValue;
                            target.Set(null, lp.Position, shortDist, origDist, topEntId, lp);
                            targetType = TargetType.Projectile;
                            target.TransferTo(w.Target, w.Comp.Session.Tick);
                            return;
                        }
                    }
                    else
                    {
                        Vector3D?hitInfo;
                        if (GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref weaponPos, ref lp.Position, out hitInfo, w.Comp.MyCube, w.Comp.Ai))
                        {
                            continue;
                        }

                        double hitDist;
                        Vector3D.Distance(ref weaponPos, ref lp.Position, out hitDist);
                        var        shortDist = hitDist;
                        var        origDist  = hitDist;
                        const long topEntId  = long.MaxValue;
                        target.Set(null, lp.Position, shortDist, origDist, topEntId, lp);
                        targetType = TargetType.Projectile;
                        target.TransferTo(w.Target, w.Comp.Session.Tick);
                        return;
                    }
                }
            }
            targetType = TargetType.None;
        }
Example #3
0
        private static bool FindRandomBlock(WeaponSystem system, GridAi ai, Target target, Vector3D weaponPos, TargetInfo info, ConcurrentCachingList <MyCubeBlock> subSystemList, Weapon w, int seed, bool checkPower = true)
        {
            var totalBlocks = subSystemList.Count;

            var topEnt = info.Target.GetTopMostParent();

            var entSphere   = topEnt.PositionComp.WorldVolume;
            var distToEnt   = MyUtils.GetSmallestDistanceToSphere(ref weaponPos, ref entSphere);
            var turretCheck = w != null;
            var topBlocks   = system.Values.Targeting.TopBlocks;
            var lastBlocks  = topBlocks > 10 && distToEnt < 1000 ? topBlocks : 10;
            var isPriroity  = false;

            if (lastBlocks < 250)
            {
                TargetInfo priorityInfo;
                if (ai.Focus.Target[0] != null && ai.Targets.TryGetValue(ai.Focus.Target[0], out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt)
                {
                    isPriroity = true;
                    lastBlocks = totalBlocks < 250 ? totalBlocks : 250;
                }
                else if (ai.Focus.Target[1] != null && ai.Targets.TryGetValue(ai.Focus.Target[1], out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt)
                {
                    isPriroity = true;
                    lastBlocks = totalBlocks < 250 ? totalBlocks : 250;
                }
            }

            if (totalBlocks < lastBlocks)
            {
                lastBlocks = totalBlocks;
            }
            var      deck           = GetDeck(ref target.BlockDeck, ref target.BlockPrevDeckLen, 0, totalBlocks, topBlocks, seed);
            var      physics        = ai.Session.Physics;
            var      iGrid          = topEnt as IMyCubeGrid;
            var      gridPhysics    = iGrid?.Physics;
            Vector3D targetLinVel   = gridPhysics?.LinearVelocity ?? Vector3D.Zero;
            Vector3D targetAccel    = (int)system.Values.HardPoint.AimLeadingPrediction > 1 ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero;
            var      notSelfHit     = false;
            var      foundBlock     = false;
            var      blocksChecked  = 0;
            var      blocksSighted  = 0;
            var      weaponRangeSqr = turretCheck ? w.MaxTargetDistanceSqr : 0;

            for (int i = 0; i < totalBlocks; i++)
            {
                if (turretCheck && (blocksChecked > lastBlocks || isPriroity && (blocksSighted > 100 || blocksChecked > 50 && ai.Session.RandomRayCasts > 500 || blocksChecked > 25 && ai.Session.RandomRayCasts > 1000)))
                {
                    break;
                }

                var card  = deck[i];
                var block = subSystemList[card];

                if (!(block is IMyTerminalBlock) || block.MarkedForClose || checkPower && !block.IsWorking)
                {
                    continue;
                }

                ai.Session.BlockChecks++;

                var    blockPos = block.CubeGrid.GridIntegerToWorld(block.Position);
                double rayDist;
                if (turretCheck)
                {
                    double distSqr;
                    Vector3D.DistanceSquared(ref blockPos, ref weaponPos, out distSqr);
                    if (distSqr > weaponRangeSqr)
                    {
                        continue;
                    }

                    blocksChecked++;
                    ai.Session.CanShoot++;
                    Vector3D predictedPos;
                    if (!Weapon.CanShootTarget(w, blockPos, targetLinVel, targetAccel, out predictedPos))
                    {
                        continue;
                    }

                    blocksSighted++;
                    Vector3D?hitPos;
                    if (!w.HitOther && GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref weaponPos, ref blockPos, out hitPos, w.Comp.MyCube, w.Comp.Ai))
                    {
                        continue;
                    }

                    ai.Session.RandomRayCasts++;
                    IHitInfo hitInfo;
                    physics.CastRay(weaponPos, blockPos, out hitInfo, 15, true);

                    if (hitInfo == null || hitInfo.HitEntity != ai.MyGrid && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf()))
                    {
                        notSelfHit = true;
                    }

                    if (hitInfo?.HitEntity == null || hitInfo.HitEntity is MyVoxelBase ||
                        hitInfo.HitEntity == ai.MyGrid)
                    {
                        continue;
                    }

                    var hitGrid = hitInfo.HitEntity as MyCubeGrid;
                    if (hitGrid != null)
                    {
                        if (hitGrid.MarkedForClose)
                        {
                            continue;
                        }
                        bool enemy;

                        var bigOwners = hitGrid.BigOwners;
                        if (bigOwners.Count == 0)
                        {
                            enemy = true;
                        }
                        else
                        {
                            var relationship = target.FiringCube.GetUserRelationToOwner(hitGrid.BigOwners[0]);
                            enemy = relationship != MyRelationsBetweenPlayerAndBlock.Owner &&
                                    relationship != MyRelationsBetweenPlayerAndBlock.FactionShare;
                        }

                        if (!enemy)
                        {
                            continue;
                        }
                    }

                    Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist);
                    var shortDist = rayDist * (1 - hitInfo.Fraction);
                    var origDist  = rayDist * hitInfo.Fraction;
                    var topEntId  = block.GetTopMostParent().EntityId;
                    target.Set(block, hitInfo.Position, shortDist, origDist, topEntId);
                    foundBlock = true;
                    break;
                }

                Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist);
                target.Set(block, block.PositionComp.WorldAABB.Center, rayDist, rayDist, block.GetTopMostParent().EntityId);
                foundBlock = true;
                break;
            }
            if (turretCheck && !notSelfHit)
            {
                w.HitOther = true;
            }
            return(foundBlock);
        }