Ejemplo n.º 1
0
        Vector3D GetSpraySoundPosition()
        {
            IMyCharacter owner = Rifle.Owner as IMyCharacter;

            if (owner != null)
            {
                MatrixD  headMatrix = owner.GetHeadMatrix(true, true);
                Vector3D soundPos   = headMatrix.Translation + headMatrix.Down * 0.1 + headMatrix.Forward * 0.6;

                // HACK: sound somehow plays ahead of position, adjusted by trial and error
                if (owner.Physics != null)
                {
                    soundPos -= owner.Physics.LinearVelocity / Constants.TICKS_PER_SECOND; // remove 1 tick worth of velocity
                }
                return(soundPos);
            }
            else
            {
                MatrixD muzzleMatrix = Rifle.GunBase.GetMuzzleWorldMatrix();
                return(muzzleMatrix.Translation + muzzleMatrix.Forward * 0.2);
            }
        }
Ejemplo n.º 2
0
        public static ConcurrentBag <MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group> FindLookAtGridGroup(IMyCharacter controlledEntity)
        {
            const float range = 5000;
            Matrix      worldMatrix;
            Vector3D    startPosition;
            Vector3D    endPosition;

            worldMatrix   = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT.
            startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
            endPosition   = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f);

            var list = new Dictionary <MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group, double>();
            var ray  = new RayD(startPosition, worldMatrix.Forward);

            foreach (var group in MyCubeGridGroups.Static.Physical.Groups)
            {
                foreach (MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Node groupNodes in group.Nodes)
                {
                    IMyCubeGrid cubeGrid = groupNodes.NodeData;

                    if (cubeGrid == null)
                    {
                        continue;
                    }

                    if (cubeGrid.Physics == null)
                    {
                        continue;
                    }

                    // check if the ray comes anywhere near the Grid before continuing.
                    if (!ray.Intersects(cubeGrid.WorldAABB).HasValue)
                    {
                        continue;
                    }

                    Vector3I?hit = cubeGrid.RayCastBlocks(startPosition, endPosition);

                    if (!hit.HasValue)
                    {
                        continue;
                    }

                    double distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length();


                    if (list.TryGetValue(group, out double oldDistance))
                    {
                        if (distance < oldDistance)
                        {
                            list.Remove(group);
                            list.Add(group, distance);
                        }
                    }
                    else
                    {
                        list.Add(group, distance);
                    }
                }
            }

            var bag = new ConcurrentBag <MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group>();

            if (list.Count == 0)
            {
                return(bag);
            }

            // find the closest Entity.
            var item = list.OrderBy(f => f.Value).First();

            bag.Add(item.Key);

            return(bag);
        }
Ejemplo n.º 3
0
        public static List <MyCubeGrid> FindLookAtGridGroup(IMyCharacter controlledEntity, long playerId, out CheckResult result)
        {
            const float range = 5000;
            Matrix      worldMatrix;
            Vector3D    startPosition;
            Vector3D    endPosition;

            var GridsGroup   = new List <MyCubeGrid>();
            var charlocation = controlledEntity.PositionComp.GetPosition();
            var sphere       = new BoundingSphereD(charlocation, range);
            var entList      = MyAPIGateway.Entities.GetTopMostEntitiesInSphere(ref sphere);

            if (entList == null || entList.Count == 0)
            {
                result = CheckResult.GRID_NOT_FOUND;
                return(GridsGroup);
            }

            worldMatrix   = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT.
            startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
            endPosition   = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f);

            var list            = new Dictionary <MyCubeGrid, double>();
            var ray             = new RayD(startPosition, worldMatrix.Forward);
            var FoundWrongOwner = false;

            foreach (var ent in entList)
            {
                if (ent is MyCubeGrid cubeGrid)
                {
                    if (cubeGrid.Physics != null)
                    {
                        // check if the ray comes anywhere near the Grid before continuing.
                        if (ray.Intersects(cubeGrid.PositionComp.WorldAABB).HasValue)
                        {
                            Vector3I?hit = cubeGrid.RayCastBlocks(startPosition, endPosition);

                            if (hit.HasValue)
                            {
                                /* We are not the server and playerId is not owner */
                                if (playerId != 0 && !OwnershipCorrect(cubeGrid, playerId))
                                {
                                    FoundWrongOwner = true;
                                    continue;
                                }

                                double distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length();

                                if (list.TryGetValue(cubeGrid, out double oldDistance))
                                {
                                    if (distance < oldDistance)
                                    {
                                        list.Remove(cubeGrid);
                                        list.Add(cubeGrid, distance);
                                    }
                                }
                                else
                                {
                                    list.Add(cubeGrid, distance);
                                }
                            }
                        }
                    }
                }
            }

            // find the closest Entity.
            if (list != null && list.Any())
            {
                var grid = list.OrderBy(f => f.Value).First().Key;

                // only here we can see attached by landing gear grids to main grid!
                var IMygrids = new List <IMyCubeGrid>();
                MyAPIGateway.GridGroups.GetGroup(grid, GridLinkTypeEnum.Physical, IMygrids);

                // convert back to MyCubeGrid
                foreach (var Mygrid in IMygrids)
                {
                    GridsGroup.Add((MyCubeGrid)Mygrid);
                }

                // sort the list. largest to smallest
                GridsGroup.SortNoAlloc((x, y) => x.BlocksCount.CompareTo(y.BlocksCount));
                GridsGroup.Reverse();
                GridsGroup.SortNoAlloc((x, y) => x.GridSizeEnum.CompareTo(y.GridSizeEnum));

                result = CheckResult.OK;
                return(GridsGroup);
            }

            if (FoundWrongOwner)
            {
                result = CheckResult.OWNED_BY_DIFFERENT_PLAYER;
            }
            else
            {
                result = CheckResult.GRID_NOT_FOUND;
            }

            return(GridsGroup);
        }
Ejemplo n.º 4
0
        void GetTarget(IMyCharacter character, out IMyCubeGrid targetGrid, out IMySlimBlock targetBlock, out IMyPlayer targetPlayer, out Vector3D aimPoint)
        {
            targetGrid   = null;
            targetBlock  = null;
            targetPlayer = null;

            bool     aiming  = Utils.IsAimingDownSights(character);
            MatrixD  head    = character.GetHeadMatrix(false, true);
            Vector3D rayDir  = head.Forward;
            Vector3D rayFrom = head.Translation;

            if (aiming)
            {
                rayFrom += rayDir * PAINT_AIM_START_OFFSET;
            }

            Vector3D rayTo = head.Translation + rayDir * PAINT_DISTANCE;

            aimPoint = rayTo;

            targetGrid = MyAPIGateway.CubeBuilder.FindClosestGrid();

            if (targetGrid == null || targetGrid.Physics == null || !targetGrid.Physics.Enabled)
            {
                targetGrid = null;
                return;
            }

            // older selection behavior when aiming down sights
            if (aiming)
            {
                Vector3I?blockPos = targetGrid.RayCastBlocks(rayFrom, rayTo);

                if (blockPos.HasValue)
                {
                    targetBlock = targetGrid.GetCubeBlock(blockPos.Value);
                }

                return;
            }

            // HACK copied and converted from MyDrillSensorRayCast.ReadEntitiesInRange() + MyCasterComponent.OnWorldPosChanged()
            // last cloned in SE v201
            #region Welder-like block selection
            hits.Clear();
            detections.Clear();
            rayOverlapResults.Clear();

            MyAPIGateway.Physics.CastRay(rayFrom, rayTo, hits, 24);

            foreach (IHitInfo hit in hits)
            {
                IMyEntity parent = hit.HitEntity?.GetTopMostParent();
                if (parent == null || parent.Physics == null || !parent.Physics.Enabled)
                {
                    continue;
                }

                Vector3D    hitPos = hit.Position;
                IMyCubeGrid grid   = parent as IMyCubeGrid;
                if (grid != null)
                {
                    // just how it's set in game code /shrug
                    hitPos += hit.Normal * -0.005f;
                }

                DetectionInfo detected;
                if (detections.TryGetValue(parent.EntityId, out detected))
                {
                    double dist1 = Vector3D.DistanceSquared(rayFrom, detected.DetectionPoint);
                    double dist2 = Vector3D.DistanceSquared(rayFrom, hitPos);
                    if (dist1 > dist2)
                    {
                        detections[parent.EntityId] = new DetectionInfo(parent, hitPos);
                    }
                }
                else
                {
                    detections[parent.EntityId] = new DetectionInfo(parent, hitPos);
                }
            }

            hits.Clear();

            LineD line = new LineD(rayFrom, rayTo);
            MyGamePruningStructure.GetAllEntitiesInRay(ref line, rayOverlapResults);

            foreach (MyLineSegmentOverlapResult <MyEntity> result in rayOverlapResults)
            {
                if (result.Element == null)
                {
                    continue;
                }

                IMyCubeBlock block = result.Element as IMyCubeBlock;
                if (block == null)
                {
                    continue;
                }

                MyCubeBlockDefinition def = (MyCubeBlockDefinition)block.SlimBlock.BlockDefinition;
                if (def.HasPhysics)
                {
                    continue; // this section is only for things that are not caught by the raycast
                }
                MyEntity parent = result.Element.GetTopMostParent();
                if (parent.Physics == null || !parent.Physics.Enabled)
                {
                    continue;
                }

                MatrixD invMatrix = block.PositionComp.WorldMatrixNormalizedInv;
                Vector3 localFrom = Vector3D.Transform(rayFrom, ref invMatrix);
                Vector3 localTo   = Vector3D.Transform(rayTo, ref invMatrix);

                float?intersectDistance = new Ray(localFrom, Vector3.Normalize(localTo - localFrom)).Intersects(block.PositionComp.LocalAABB) + 0.01f;
                if (intersectDistance.HasValue && intersectDistance <= PAINT_DISTANCE)
                {
                    Vector3D      hitPos = rayFrom + rayDir * intersectDistance.Value;
                    DetectionInfo detected;
                    if (detections.TryGetValue(parent.EntityId, out detected))
                    {
                        double dist1 = Vector3D.DistanceSquared(rayFrom, detected.DetectionPoint);
                        double dist2 = Vector3D.DistanceSquared(rayFrom, hitPos);
                        if (dist1 > dist2)
                        {
                            detections[parent.EntityId] = new DetectionInfo(parent, hitPos);
                        }
                    }
                    else
                    {
                        detections[parent.EntityId] = new DetectionInfo(parent, hitPos);
                    }
                }
            }

            rayOverlapResults.Clear();

            if (detections.Count == 0)
            {
                return;
            }

            double        closetDist = double.MaxValue;
            DetectionInfo closestObj = new DetectionInfo(null, Vector3D.Zero);

            foreach (DetectionInfo detected in detections.Values)
            {
                double dist = Vector3D.DistanceSquared(detected.DetectionPoint, rayFrom);
                if (dist < closetDist)
                {
                    closestObj = detected;
                    closetDist = dist;
                }
            }

            detections.Clear();

            targetGrid = closestObj.Entity as IMyCubeGrid;
            if (targetGrid == null)
            {
                return;
            }

            Vector3D localPos = Vector3D.Transform(closestObj.DetectionPoint, targetGrid.WorldMatrixNormalizedInv);
            Vector3I cube;
            targetGrid.FixTargetCube(out cube, localPos / targetGrid.GridSize);
            targetBlock = targetGrid.GetCubeBlock(cube);
            #endregion Welder-like block selection
        }