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}"); } }
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}"); } }