Beispiel #1
0
        private static bool AcquireBlock(WeaponSystem system, GridAi ai, Target target, TargetInfo info, Vector3D weaponPos, WeaponRandomGenerator wRng, RandomType type, ref BoundingSphereD waterSphere, Weapon w = null, bool checkPower = true)
        {
            if (system.TargetSubSystems)
            {
                var subSystems     = system.Values.Targeting.SubSystems;
                var targetLinVel   = info.Target.Physics?.LinearVelocity ?? Vector3D.Zero;
                var targetAccel    = (int)system.Values.HardPoint.AimLeadingPrediction > 1 ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero;
                var focusSubSystem = w != null && w.Comp.Data.Repo.Base.Set.Overrides.FocusSubSystem;

                foreach (var blockType in subSystems)
                {
                    var bt = focusSubSystem ? w.Comp.Data.Repo.Base.Set.Overrides.SubSystem : blockType;

                    ConcurrentDictionary <BlockTypes, ConcurrentCachingList <MyCubeBlock> > blockTypeMap;
                    system.Session.GridToBlockTypeMap.TryGetValue((MyCubeGrid)info.Target, out blockTypeMap);
                    if (bt != Any && blockTypeMap != null && blockTypeMap[bt].Count > 0)
                    {
                        var subSystemList = blockTypeMap[bt];
                        if (system.ClosestFirst)
                        {
                            if (target.Top5.Count > 0 && (bt != target.LastBlockType || target.Top5[0].CubeGrid != subSystemList[0].CubeGrid))
                            {
                                target.Top5.Clear();
                            }

                            target.LastBlockType = bt;
                            if (GetClosestHitableBlockOfType(subSystemList, ai, target, weaponPos, targetLinVel, targetAccel, ref waterSphere, w, checkPower))
                            {
                                return(true);
                            }
                        }
                        else if (FindRandomBlock(system, ai, target, weaponPos, info, subSystemList, w, wRng, type, ref waterSphere, checkPower))
                        {
                            return(true);
                        }
                    }

                    if (focusSubSystem)
                    {
                        break;
                    }
                }

                if (system.OnlySubSystems || focusSubSystem && w.Comp.Data.Repo.Base.Set.Overrides.SubSystem != Any)
                {
                    return(false);
                }
            }
            FatMap fatMap;

            return(system.Session.GridToFatMap.TryGetValue((MyCubeGrid)info.Target, out fatMap) && fatMap.MyCubeBocks != null && FindRandomBlock(system, ai, target, weaponPos, info, fatMap.MyCubeBocks, w, wRng, type, ref waterSphere, checkPower));
        }
Beispiel #2
0
        private static bool FindRandomBlock(WeaponSystem system, GridAi ai, Target target, Vector3D weaponPos, TargetInfo info, ConcurrentCachingList <MyCubeBlock> subSystemList, Weapon w, WeaponRandomGenerator wRng, RandomType type, ref BoundingSphereD waterSphere, 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;
                MyEntity   fTarget;
                if (ai.Construct.Data.Repo.FocusData.Target[0] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[0], out fTarget) && ai.Targets.TryGetValue(fTarget, out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt)
                {
                    isPriroity = true;
                    lastBlocks = totalBlocks < 250 ? totalBlocks : 250;
                }
                else if (ai.Construct.Data.Repo.FocusData.Target[1] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[1], out fTarget) && ai.Targets.TryGetValue(fTarget, 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, wRng, type);
            var      physics       = system.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      foundBlock    = false;
            var      blocksChecked = 0;
            var      blocksSighted = 0;

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

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

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

                system.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 > w.MaxTargetDistanceSqr || distSqr < w.MinTargetDistanceSqr)
                    {
                        continue;
                    }

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

                    if (system.Session.WaterApiLoaded && waterSphere.Radius > 2 && waterSphere.Contains(predictedPos) != ContainmentType.Disjoint)
                    {
                        continue;
                    }

                    blocksSighted++;

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

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

                    var hitGrid = hitInfo.HitEntity as MyCubeGrid;
                    if (hitGrid != null)
                    {
                        if (hitGrid.MarkedForClose || hitGrid != block.CubeGrid && hitGrid.IsSameConstructAs(ai.MyGrid))
                        {
                            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;
            }
            return(foundBlock);
        }
Beispiel #3
0
        private static int[] GetDeck(ref int[] deck, ref int prevDeckLen, int firstCard, int cardsToSort, int cardsToShuffle, WeaponRandomGenerator rng, RandomType type)
        {
            var count = cardsToSort - firstCard;

            if (prevDeckLen < count)
            {
                deck        = new int[count];
                prevDeckLen = count;
            }

            Random rnd;

            if (type == RandomType.Acquire)
            {
                rnd = rng.AcquireRandom;
                rng.AcquireCurrentCounter += count;
            }
            else
            {
                rnd = rng.ClientProjectileRandom;
                rng.ClientProjectileCurrentCounter += count;
            }

            for (int i = 0; i < count; i++)
            {
                var j = i < cardsToShuffle?rnd.Next(i + 1) : i;

                deck[i] = deck[j];
                deck[j] = firstCard + i;
            }
            return(deck);
        }