Пример #1
0
        private void BlockIntersect(MyCubeGrid breaching, ref MyOrientedBoundingBoxD bOriBBoxD, ref EntIntersectInfo entInfo)
        {
            try
            {
                if (entInfo == null || breaching == null || breaching.MarkedForClose)
                {
                    return;
                }

                //Quaternion quadMagic;
                //Quaternion.Divide(ref bOriBBoxD.Orientation, ref SOriBBoxD.Orientation, out quadMagic);
                //var sMatrix = DetectMatrixOutsideInv;

                if (bOriBBoxD.Intersects(ref SOriBBoxD))
                //if (CustomCollision.IntersectEllipsoidObb(ref sMatrix, ref bOriBBoxD.Center, ref bOriBBoxD.HalfExtent, ref SOriBBoxD.HalfExtent, ref quadMagic))
                {
                    if (_tick - entInfo.RefreshTick == 0 || entInfo.CacheBlockList.IsEmpty)
                    {
                        entInfo.CacheBlockList.ClearImmediate();
                        RefreshBlockCache(breaching, entInfo);
                    }

                    var       collisionAvg = Vector3D.Zero;
                    const int blockDmgNum  = 250;

                    var rawDamage = 0f;
                    var hits      = 0;

                    var cubeHitSet = Session.Instance.SetCubeAccelPool.Get();
                    var sMat       = DetectMatrixOutside;

                    for (int i = 0; i < entInfo.CacheBlockList.Count; i++)
                    {
                        var accel = entInfo.CacheBlockList[i];
                        if (_isServer && (accel.Block == null || accel.Block.CubeGrid != breaching))
                        {
                            continue;
                        }

                        if (accel.Block == null || accel.Block.CubeGrid != breaching || accel.Block.IsDestroyed)
                        {
                            continue;
                        }

                        var block = accel.Block;
                        var point = CustomCollision.BlockIntersect(block, accel.CubeExists, ref bOriBBoxD, ref sMat, ref DetectMatrixOutsideInv, ref _blockPoints);
                        if (point == null)
                        {
                            continue;
                        }

                        collisionAvg += (Vector3D)point;
                        hits++;
                        if (!_isServer)
                        {
                            continue;
                        }

                        rawDamage += block.Integrity;
                        if (Session.Enforced.DisableBlockDamage == 0)
                        {
                            cubeHitSet.Add(accel);
                        }

                        if (hits > blockDmgNum)
                        {
                            break;
                        }
                    }

                    if (collisionAvg != Vector3D.Zero)
                    {
                        collisionAvg /= hits;
                        ComputeCollisionPhysics(breaching, MyGrid, collisionAvg);
                        entInfo.Touched = true;
                    }
                    else
                    {
                        return;
                    }
                    if (!_isServer)
                    {
                        return;
                    }

                    var damage = rawDamage * DsState.State.ModulateEnergy;

                    var blockEvent = Session.Instance.ManyBlocksPool.Get();
                    blockEvent.Init(cubeHitSet, this, damage, collisionAvg, breaching.EntityId);

                    Session.Instance.ThreadEvents.Enqueue(blockEvent);
                }
            }
            catch (Exception ex) { Log.Line($"Exception in BlockIntersect: {ex}"); }
        }
Пример #2
0
        private void BlockIntersect(MyCubeGrid breaching, MyOrientedBoundingBoxD bOriBBoxD, ref EntIntersectInfo entInfo)
        {
            try
            {
                if (entInfo == null || breaching == null || breaching.MarkedForClose)
                {
                    return;
                }

                if (bOriBBoxD.Intersects(ref SOriBBoxD))
                {
                    var collisionAvg = Vector3D.Zero;
                    var damageBlocks = Session.Enforced.DisableBlockDamage == 0;
                    var bQuaternion  = Quaternion.CreateFromRotationMatrix(breaching.WorldMatrix);

                    const int blockDmgNum = 250;

                    var rawDamage       = 0f;
                    var blockSize       = breaching.GridSize;
                    var scaledBlockSize = blockSize * 3;
                    var gc = breaching.WorldToGridInteger(DetectionCenter);
                    var rc = ShieldSize.AbsMax() / blockSize;
                    rc *= rc;
                    rc  = rc + 1;
                    rc  = Math.Ceiling(rc);
                    var hits        = 0;
                    var blockPoints = new Vector3D[9];

                    var cloneCacheList = Session.Instance.ListCubeAccelPool.Get();
                    cloneCacheList.AddRange(entInfo.CacheBlockList);
                    var cubeHitSet = Session.Instance.SetCubeAccelPool.Get();

                    for (int i = 0; i < cloneCacheList.Count; i++)
                    {
                        var accel    = cloneCacheList[i];
                        var blockPos = accel.BlockPos;
                        var num1     = gc.X - blockPos.X;
                        var num2     = gc.Y - blockPos.Y;
                        var num3     = gc.Z - blockPos.Z;
                        var result   = (num1 * num1) + (num2 * num2) + (num3 * num3);

                        if (_isServer)
                        {
                            if (result > rc || accel.CubeExists && result > rc + scaledBlockSize)
                            {
                                continue;
                            }
                            if (accel.Block == null || accel.Block.CubeGrid != breaching)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            if (hits > blockDmgNum)
                            {
                                break;
                            }
                            if (result > rc || accel.CubeExists && result > rc + scaledBlockSize || accel.Block == null || accel.Block.CubeGrid != breaching || accel.Block.IsDestroyed)
                            {
                                continue;
                            }
                        }

                        var block = accel.Block;
                        var point = CustomCollision.BlockIntersect(block, accel.CubeExists, bQuaternion, DetectMatrixOutside, DetectMatrixOutsideInv, ref blockPoints);
                        if (point == null)
                        {
                            continue;
                        }
                        collisionAvg += (Vector3D)point;
                        hits++;
                        if (!_isServer)
                        {
                            continue;
                        }

                        if (hits > blockDmgNum)
                        {
                            break;
                        }

                        rawDamage += block.Integrity;
                        if (damageBlocks)
                        {
                            cubeHitSet.Add(accel);
                        }
                    }
                    cloneCacheList.Clear();
                    Session.Instance.ListCubeAccelPool.Return(cloneCacheList);

                    if (collisionAvg != Vector3D.Zero)
                    {
                        collisionAvg /= hits;
                        ComputeCollisionPhysics(breaching, MyGrid, collisionAvg);
                        entInfo.Touched = true;
                    }
                    else
                    {
                        return;
                    }
                    if (!_isServer)
                    {
                        return;
                    }

                    var damage = rawDamage * DsState.State.ModulateEnergy;

                    var blockEvent = Session.Instance.ManyBlocksPool.Get();
                    blockEvent.Init(cubeHitSet, this, damage, collisionAvg, breaching.EntityId);

                    Session.Instance.ThreadEvents.Enqueue(blockEvent);
                }
            }
            catch (Exception ex) { Log.Line($"Exception in BlockIntersect: {ex}"); }
        }