public override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); m_updateCounter++; if (m_updateCounter % 100 == 0 && MySession.Static.LocalCharacter != null) { m_detectedGrids.Clear(); BoundingSphereD playerSphere = new BoundingSphereD(MySession.Static.LocalCharacter.PositionComp.GetPosition(), 500f); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref playerSphere, m_detectedGrids); for (int i = 0; i < m_detectedGrids.Count; i++) { MyCubeGrid grid = m_detectedGrids[i] as MyCubeGrid; if (grid != null) { foreach (var block in grid.CubeBlocks) { if (block.FatBlock is MyFunctionalBlock) { (block.FatBlock as MyFunctionalBlock).UpdateSoundEmitters(); } } } } } }
/// <summary> /// Destroys missiles in blast radius. /// </summary> private void DestroyAllNearbyMissiles() { if (myCluster != null || m_destroyedNearbyMissiles) { return; } m_destroyedNearbyMissiles = true; BoundingSphereD explosion = new BoundingSphereD(MyEntity.GetPosition(), myAmmo.MissileDefinition.MissileExplosionRadius); Log.DebugLog("Explosion: " + explosion); List <MyEntity> entitiesInExplosion = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref explosion, entitiesInExplosion, MyEntityQueryType.Dynamic); foreach (MyEntity entity in entitiesInExplosion) { if (!entity.Closed && entity.IsMissile() && entity != MyEntity) { Log.DebugLog("Explode: " + entity + ", position: " + entity.PositionComp.GetPosition()); ((MyAmmoBase)entity).Explode(); } } explosion.Radius *= 10f; entitiesInExplosion.Clear(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref explosion, entitiesInExplosion, MyEntityQueryType.Dynamic); foreach (MyEntity entity in entitiesInExplosion) { if (!entity.Closed && entity.IsMissile() && entity != MyEntity) { Log.DebugLog("nearby: " + entity + ", position: " + entity.PositionComp.GetPosition()); } } }
/// <summary> /// Takes a point and radius and returns all entities found within the sphere /// </summary> /// <param name="detectionCenter">Point of scan origin</param> /// <param name="range">How far from the origin you want to scan for entities</param> /// <returns>An enumerable list of entities</returns> public IEnumerable <MyEntity> DetectEntitiesInSphere(Vector3D detectionCenter, double range) { BoundingSphereD pruneSphere = new BoundingSphereD(detectionCenter, range); List <MyEntity> pruneList = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref pruneSphere, pruneList, MyEntityQueryType.Dynamic); return(pruneList); }
public bool SpaceCollisionDetection(Vector3D detectionCenter) { BoundingSphereD locationSphere = new BoundingSphereD(detectionCenter, 75); List <MyEntity> pruneList = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref locationSphere, pruneList, MyEntityQueryType.Both); return(pruneList.Count > 0); }
private void GetNearby(float range) { if (m_nearbyRange < range) { range++; m_nearbyEntities.Clear(); BoundingSphereD nearby = new BoundingSphereD(Entity.GetPosition(), range); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref nearby, m_nearbyEntities); m_nearbyRange = range; } }
public void CleanupAsteroids(bool deleteStorage = false) { var voxelMaps = MyEntities.GetEntities().OfType <MyVoxelMap>(); var resetIds = new List <long>(); //Parallel.ForEach(voxelMaps, map => foreach (var map in voxelMaps) { try { if (map.StorageName == null || map.Storage.DataProvider == null) { continue; } var s = map.PositionComp.WorldVolume; var nearEntities = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref s, nearEntities); if (nearEntities.Any(e => e is MyCubeGrid || e is MyCharacter)) { continue; } long id = map.EntityId; if (deleteStorage) { map.Close(); } else { map.Storage.Reset(MyStorageDataTypeFlags.All); } if (!deleteStorage) { lock (resetIds) resetIds.Add(id); } } catch (Exception e) { _log.Error($"{e.Message}\n{e.StackTrace}"); } } //); ModCommunication.SendMessageToClients(new VoxelResetMessage(resetIds.ToArray())); Context.Respond($"Reset {resetIds.Count} voxel maps."); }
protected virtual void UpdateInternal() { if (this.DoQuery) { this.m_queryResult.Clear(); TriggerType triggerType = this.m_triggerType; if (triggerType == TriggerType.AABB) { MyGamePruningStructure.GetTopMostEntitiesInBox(ref this.m_AABB, this.m_queryResult, MyEntityQueryType.Both); } else { if (triggerType != TriggerType.Sphere) { throw new ArgumentOutOfRangeException(); } MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref this.m_boundingSphere, this.m_queryResult, MyEntityQueryType.Both); } int index = 0; while (index < this.m_queryResult.Count) { MyEntity entity = this.m_queryResult[index]; if (!this.QueryEvaluator(entity)) { this.m_queryResult.RemoveAtFast <MyEntity>(index); continue; } triggerType = this.m_triggerType; if (triggerType == TriggerType.AABB) { if (!this.m_AABB.Intersects(this.m_queryResult[index].PositionComp.WorldAABB)) { this.m_queryResult.RemoveAtFast <MyEntity>(index); continue; } index++; continue; } if (triggerType != TriggerType.Sphere) { index++; continue; } if (!this.m_boundingSphere.Intersects(this.m_queryResult[index].PositionComp.WorldAABB)) { this.m_queryResult.RemoveAtFast <MyEntity>(index); continue; } index++; } } }
public static IEnumerable <MyEntity> DetectTopMostEntitiesInSphere(Vector3D detectionCenter, double range, bool reportOrigin = false) { if (reportOrigin) { AddGpsLocation($"DetectTopMostEntitiesInSphere {range}", detectionCenter); } BoundingSphereD pruneSphere = new BoundingSphereD(detectionCenter, range); List <MyEntity> pruneList = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref pruneSphere, pruneList); return(pruneList); }
public void CleanupAsteroidsDistant(double distance = 1000, bool deleteStorage = false) { var voxelMaps = MyEntities.GetEntities().OfType <MyVoxelMap>(); var resetIds = new List <long>(); int count = 0; foreach (var map in voxelMaps) { try { if (map.StorageName == null || map.Storage.DataProvider == null) { continue; } var s = new BoundingSphereD(map.PositionComp.GetPosition(), distance); var nearEntities = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref s, nearEntities); if (nearEntities.Any(e => e is MyCubeGrid || e is MyCharacter)) { continue; } count++; long id = map.EntityId; if (deleteStorage) { using (PinDelete()) map.Close(); } else { map.Storage.Reset(MyStorageDataTypeFlags.All); resetIds.Add(id); } } catch (Exception e) { _log.Error($"{e.Message}\n{e.StackTrace}"); } } ModCommunication.SendMessageToClients(new VoxelResetMessage(resetIds.ToArray())); Context.Respond($"Reset {count} voxel maps."); }
public static void ApplyEMP(BoundingSphereD location, float strength, TimeSpan duration) { MyAPIGateway.Utilities.TryInvokeOnGameThread(() => { MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref location, s_entitiesEMP); foreach (IMyEntity entity in s_entitiesEMP) { IMyCubeGrid grid = entity as IMyCubeGrid; if (grid != null) { EMP e = new EMP(); e.Start(grid, duration, ref strength, long.MinValue); } } s_entitiesEMP.Clear(); }); }
public static void GetRealPlayers(Vector3D center, float radius, List <long> realPlayers) { List <IMyIdentity> realPlayersIdentities = new List <IMyIdentity>(); MyAPIGateway.Players.GetAllIdentites(realPlayersIdentities, p => !string.IsNullOrEmpty(p?.DisplayName)); var pruneSphere = new BoundingSphereD(center, radius); var pruneList = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref pruneSphere, pruneList); foreach (var ent in pruneList) { if (ent == null || !(ent is IMyCubeGrid || ent is IMyCharacter)) { continue; } IMyPlayer player = null; if (ent is IMyCharacter) { player = MyAPIGateway.Players.GetPlayerControllingEntity(ent); if (player == null) { continue; } } else { var playerTmp = MyAPIGateway.Players.GetPlayerControllingEntity(ent); if (playerTmp?.Character != null) { player = playerTmp; } } if (player == null) { continue; } if (realPlayersIdentities.Contains(player.Identity)) { realPlayers.Add(player.IdentityId); } } }
private void DrawDisabledGuns() { if (Tick600 || Tick60 && QuickDisableGunsCheck) { QuickDisableGunsCheck = false; _nearbyGridsTestSphere.Center = CameraPos; _gridsNearCamera.Clear(); _uninitializedBlocks.Clear(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref _nearbyGridsTestSphere, _gridsNearCamera); for (int i = _gridsNearCamera.Count - 1; i >= 0; i--) { var grid = _gridsNearCamera[i] as MyCubeGrid; if (grid?.Physics != null && !grid.MarkedForClose && !grid.IsPreview && !grid.Physics.IsPhantom) { var fatBlocks = grid.GetFatBlocks(); for (int j = 0; j < fatBlocks.Count; j++) { var block = fatBlocks[j]; if (block.IsFunctional && WeaponPlatforms.ContainsKey(block.BlockDefinition.Id)) { GridAi gridAi; if (!GridTargetingAIs.TryGetValue(block.CubeGrid, out gridAi) || !gridAi.WeaponBase.ContainsKey(block)) { _uninitializedBlocks.Add(block); } } } } } } for (int i = 0; i < _uninitializedBlocks.Count; i++) { var badBlock = _uninitializedBlocks[i]; if (badBlock.InScene) { var lookSphere = new BoundingSphereD(badBlock.PositionComp.WorldAABB.Center, 30f); if (Camera.IsInFrustum(ref lookSphere)) { MyOrientedBoundingBoxD blockBox; SUtils.GetBlockOrientedBoundingBox(badBlock, out blockBox); DsDebugDraw.DrawBox(blockBox, _uninitializedColor); } } } }
internal void ComputeAccelSphere() { NearByEntityCache.Clear(); if (MarkedForClose) { return; } AccelChecked = true; var numOfEntities = NearByEntities > 0 ? NearByEntities : 1f; var ratio = (MyProjectiles / numOfEntities) / 10f; var checkVol = Math.Max(ratio > 1 ? ScanVolume.Radius : ScanVolume.Radius * ratio, 500f); NearByEntitySphere = new BoundingSphereD(MyGrid.PositionComp.WorldAABB.Center, checkVol); var qType = ClosestStaticSqr < (checkVol * 2) * (checkVol * 2) ? MyEntityQueryType.Both : MyEntityQueryType.Dynamic; MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref NearByEntitySphere, NearByEntityCache, qType); }
public override void UpdateBeforeSimulation() { if (HyperDriveLogic.hyperDriveBlock.Enabled) { //var viewDistance = Session.SessionSettings.ViewDistance; var viewSphere = new BoundingSphereD(MyAPIGateway.Session.Player.GetPosition(), 50000); var entList = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref viewSphere, entList); foreach (var v in entList) { if (v == HyperDriveLogic.hyperDriveBlock.CubeGrid) { continue; } if (HyperDriveLogic.hyper && HyperDriveLogic.hyperFactor > 30) { if (v is MyVoxelBase) { var myBase = v as MyVoxelBase; if (myBase.ContentChanged) { continue; } v.Physics.Enabled = false; v.Render.UpdateRenderObject(false); } else { v.Render.UpdateRenderObject(false); } } else if (!HyperDriveLogic.hyper) { if (v is MyVoxelBase) { v.Physics.Enabled = true; } v.Render.UpdateRenderObject(true); } } } }
// This is broken as f**k public static IEnumerable <MyEntity> DetectPlayersInSphere(Vector3D detectionCenter, double range, bool reportOrigin = false) { if (reportOrigin) { AddGpsLocation($"DetectPlayersInSphere {range}", detectionCenter); } BoundingSphereD pruneSphere = new BoundingSphereD(detectionCenter, range); List <MyEntity> pruneList = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref pruneSphere, pruneList); List <IMyPlayer> players = new List <IMyPlayer>(); MyAPIGateway.Multiplayer.Players.GetPlayers(players, x => ValidPlayer(x.IdentityId)); pruneList.RemoveAll(x => players.Any(y => y.IdentityId != x.EntityId)); foreach (MyEntity ent in pruneList) { AddGpsLocation($"DetectPlayersInSphere ({range}): {((IMyEntity)ent).DisplayName}", ((IMyEntity)ent).GetPosition()); } return(pruneList); }
void FindFloatingObjects() { var entities = Mod.Entities; entities.Clear(); floatingObjects.Clear(); if (Range < RANGE_OFF_EXCLUSIVE || !block.IsWorking || !block.CubeGrid.Physics.Enabled) { if ((NeedsUpdate & MyEntityUpdateEnum.EACH_FRAME) != 0) { UpdateEmissive(); NeedsUpdate &= ~MyEntityUpdateEnum.EACH_FRAME; } return; } if ((NeedsUpdate & MyEntityUpdateEnum.EACH_FRAME) == 0) { NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME; } var collectPos = block.WorldMatrix.Translation + (block.WorldMatrix.Forward * offset); var sphere = new BoundingSphereD(collectPos, Range + 10); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities, MyEntityQueryType.Dynamic); foreach (var ent in entities) { var floatingObject = ent as IMyFloatingObject; if (floatingObject != null && floatingObject.Physics != null) { floatingObjects.Add(floatingObject); } } entities.Clear(); }
/// <summary> /// Returns the closest grid to the position /// </summary> public static MyCubeGrid GetApproximateGrid(Vector3 position, MyEntityQueryType queryType = MyEntityQueryType.Both) { BoundingSphereD sphere = new BoundingSphereD(position, 1); List <MyEntity> entities = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities, queryType); foreach (var entity in entities) { if (entity.IsPreview || entity.Physics == null) { continue; } if (entity is MyCubeGrid) { return(entity as MyCubeGrid); } } entities.Clear(); return(null); }
/// <summary> /// Checks if a position is airtight /// </summary> public static bool IsPositionAirtight(Vector3D position) { if (!MyAPIGateway.Session.SessionSettings.EnableOxygenPressurization) { return(false); } BoundingSphereD sphere = new BoundingSphereD(position, 5); List <MyEntity> entities = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities); foreach (var entity in entities) { MyCubeGrid grid = entity as MyCubeGrid; if (grid != null && grid.IsRoomAtPositionAirtight(grid.WorldToGridInteger(position))) { return(true); } } return(false); }
private void PrepEmpBlast() { var stackCount = 0; var warHeadSize = 0; var warHeadYield = 0d; var epiCenter = Vector3D.Zero; WarHeadBlast empChild; while (EmpStore.TryDequeue(out empChild)) { if (empChild.CustomData.Contains("@EMP")) { stackCount++; warHeadSize = empChild.WarSize; warHeadYield = empChild.Yield; epiCenter += empChild.Position; } } if (stackCount == 0) { EmpWork.EventComplete(); return; } epiCenter /= stackCount; var rangeCap = MathHelper.Clamp(stackCount * warHeadYield, warHeadYield, SyncDist); _warHeadGridHits.Clear(); _pruneWarGrids.Clear(); var sphere = new BoundingSphereD(epiCenter, rangeCap); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, _pruneWarGrids); foreach (var ent in _pruneWarGrids) { var grid = ent as MyCubeGrid; if (grid != null) { ShieldGridComponent sComp; grid.Components.TryGet(out sComp); if (sComp?.DefenseShields != null && sComp.DefenseShields.NotFailed) { continue; } var gridCenter = grid.PositionComp.WorldVolume.Center; var testDir = Vector3D.Normalize(gridCenter - epiCenter); var impactPos = gridCenter + (testDir * -grid.PositionComp.WorldVolume.Radius); IHitInfo hitInfo; MyAPIGateway.Physics.CastRay(epiCenter, impactPos, out hitInfo, CollisionLayers.DefaultCollisionLayer); if (hitInfo?.HitEntity == null) { _warHeadGridHits.Add(grid); } } } EmpWork.StoreEmpBlast(epiCenter, warHeadSize, warHeadYield, stackCount, rangeCap); }
internal void SeekEnemy() { var mineInfo = Info.ConsumableDef.Trajectory.Mines; var detectRadius = mineInfo.DetectRadius; var deCloakRadius = mineInfo.DeCloakRadius; var wakeRadius = detectRadius > deCloakRadius ? detectRadius : deCloakRadius; PruneSphere = new BoundingSphereD(Position, wakeRadius); var inRange = false; var activate = false; var minDist = double.MaxValue; if (!MineActivated) { MyEntity closestEnt = null; MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref PruneSphere, MyEntityList, MyEntityQueryType.Dynamic); for (int i = 0; i < MyEntityList.Count; i++) { var ent = MyEntityList[i]; var grid = ent as MyCubeGrid; var character = ent as IMyCharacter; if (grid == null && character == null || ent.MarkedForClose || !ent.InScene) { continue; } Sandbox.ModAPI.Ingame.MyDetectedEntityInfo entInfo; bool peace; MyRelationsBetweenPlayerAndBlock newRelation; if (!Info.Ai.CreateEntInfo(ent, Info.Ai.AiOwner, out entInfo)) { continue; } switch (entInfo.Relationship) { case MyRelationsBetweenPlayerAndBlock.Owner: continue; case MyRelationsBetweenPlayerAndBlock.FactionShare: continue; } var entSphere = ent.PositionComp.WorldVolume; entSphere.Radius += Info.ConsumableDef.Const.CollisionSize; var dist = MyUtils.GetSmallestDistanceToSphereAlwaysPositive(ref Position, ref entSphere); if (dist >= minDist) { continue; } minDist = dist; closestEnt = ent; } MyEntityList.Clear(); if (closestEnt != null) { ForceNewTarget(); Info.Target.Entity = closestEnt; } } else if (Info.Target.Entity != null && !Info.Target.Entity.MarkedForClose) { var entSphere = Info.Target.Entity.PositionComp.WorldVolume; entSphere.Radius += Info.ConsumableDef.Const.CollisionSize; minDist = MyUtils.GetSmallestDistanceToSphereAlwaysPositive(ref Position, ref entSphere); } else { TriggerMine(true); } if (EnableAv) { if (Info.AvShot.Cloaked && minDist <= deCloakRadius) { Info.AvShot.Cloaked = false; } else if (Info.AvShot.ConsumableDef.Trajectory.Mines.Cloak && !Info.AvShot.Cloaked && minDist > deCloakRadius) { Info.AvShot.Cloaked = true; } } if (minDist <= Info.ConsumableDef.Const.CollisionSize) { activate = true; } if (minDist <= detectRadius) { inRange = true; } if (MineActivated) { if (!inRange) { TriggerMine(true); } } else if (inRange) { ActivateMine(); } if (activate) { TriggerMine(false); MyEntityList.Add(Info.Target.Entity); } }
void Scan() { m_lastScan = MySession.Static.GameplayFrameCounter; ProfilerShort.Begin("QueryTargets"); BoundingSphereD bs = new BoundingSphereD(Vector3D.Transform(m_queryLocal.Center, m_grid.WorldMatrix), m_queryLocal.Radius); m_targetRoots.Clear(); m_targetBlocks.Clear(); ProfilerShort.Begin("MyGamePruningStructure.GetAllTop..."); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref bs, m_targetRoots); ProfilerShort.End(); int targetCount = m_targetRoots.Count; m_ownersA.AddList(m_grid.SmallOwners); m_ownersA.AddList(m_grid.BigOwners); for (int i = 0; i < targetCount; i++) { var grid = m_targetRoots[i] as MyCubeGrid; //perf: using grid owners to not querry friendly ships for blocks if (grid != null) { if (grid.Physics != null && !grid.Physics.Enabled) { continue; } ProfilerShort.Begin("Friend checks"); bool enemy = false; if (grid.BigOwners.Count == 0 && grid.SmallOwners.Count == 0) { foreach (var owner in m_ownersA) { if (MyIDModule.GetRelation(owner, 0) == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies) { enemy = true; break; } } } else { m_ownersB.AddList(grid.BigOwners); m_ownersB.AddList(grid.SmallOwners); foreach (var owner in m_ownersA) { foreach (var other in m_ownersB) { if (MyIDModule.GetRelation(owner, other) == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies) { enemy = true; break; } } } m_ownersB.Clear(); } ProfilerShort.End(); if (enemy) { ProfilerShort.Begin("grid.Hierarchy.QuerySphere"); var list = m_targetBlocks.GetOrAddList(grid); grid.Hierarchy.QuerySphere(ref bs, list); ProfilerShort.End(); } else { MyIDModule module; //performance unfriendly case when grid is not clearly neutral or enemy foreach (var block in grid.GetFatBlocks()) { var moduleOwner = ((MyEntity)block) as IMyComponentOwner <MyIDModule>; if (!(moduleOwner != null && moduleOwner.GetComponent(out module))) { continue; } var myID = block.OwnerId; foreach (var owner in m_ownersA) { if (MyIDModule.GetRelation(owner, myID) == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies) { enemy = true; break; } } if (enemy) { break; } } if (enemy) { ProfilerShort.Begin("grid.Hierarchy.QuerySphere"); var list = m_targetBlocks.GetOrAddList(grid); grid.Hierarchy.QuerySphere(ref bs, list); ProfilerShort.End(); } } } } m_ownersA.Clear(); ProfilerShort.Begin("Filter small objects"); for (int i = m_targetRoots.Count - 1; i >= 0; i--) { var target = m_targetRoots[i]; if (target is Sandbox.Game.Entities.Debris.MyDebrisBase || target is MyFloatingObject || (target.Physics != null && !target.Physics.Enabled) || target.GetTopMostParent().Physics == null || !target.GetTopMostParent().Physics.Enabled) { m_targetRoots.RemoveAtFast(i); } } ProfilerShort.End(); ProfilerShort.End(); }
/// <summary> /// Called when a node is reached. Tests against targets and creates new nodes. /// </summary> /// <param name="pnSet">The active set.</param> /// <param name="currentNode">The node that was reached.</param> /// <param name="input">Param for CanTravelSegment, Offset and Direction should be correct.</param> /// <param name="proximity">Result from CanTravelSegment, how close the ship would come to an entity when traveling to this node from its parent.</param> private void ReachedNode(FindingSet pnSet, ref PathNode currentNode, ref PathTester.TestInput input, float proximity) { // impose a penalty for going near entities, this does not affect this node but will affect its children // this really helps prevent pathfinder getting stuck but the penalty might be too high float penalty = 10f * (100f - MathHelper.Clamp(proximity, 0f, 100f)); Log.DebugLog(SetName(pnSet) + " Reached node: " + ReportRelativePosition(currentNode.Position) + " from " + ReportRelativePosition(pnSet.m_reachedNodes[currentNode.ParentKey].Position) + ", reached: " + pnSet.m_reachedNodes.Count + ", open: " + pnSet.m_openNodes.Count + ", proximity: " + proximity + ", penalty: " + penalty); currentNode.DistToCur += penalty; long cNodePosHash = currentNode.Key; pnSet.m_reachedNodes.Add(cNodePosHash, currentNode); if (!m_canChangeCourse) { // test from current node position to destination Log.DebugLog(SetName(pnSet) + " Running backwards search", Logger.severity.ERROR, condition: pnSet != m_forward); Vector3D.Subtract(ref m_currentPosition, ref pnSet.m_referencePosition, out input.Offset); input.Length = (float)Vector3D.Distance(currentNode.Position, pnSet.m_referencePosition); if (CanTravelSegment(ref input, out proximity)) { Log.DebugLog(SetName(pnSet) + " Reached destination from node: " + ReportRelativePosition(currentNode.Position)); Log.DebugLog("Backwards start is not reference position", Logger.severity.ERROR, condition: m_backwardList[0].m_startPosition != pnSet.m_referencePosition); BuildPath(cNodePosHash, m_backwardList[0], pnSet.m_referencePosition.GetHash()); return; } #if SHOW_REACHED ShowPosition(currentNode, SetName(pnSet)); #endif return; } foreach (PathNodeSet target in pnSet.m_targets) { if (target.HasReached(cNodePosHash)) { Log.DebugLog(SetName(pnSet) + " Opposite set has same position"); if (pnSet == m_forward) { BuildPath(cNodePosHash, target, cNodePosHash); } else { BuildPath(cNodePosHash, pnSet, cNodePosHash); } return; } } Vector3D obstructPosition = m_obstructingEntity.GetPosition(); Vector3D currentNodeWorld; Vector3D.Add(ref obstructPosition, ref currentNode.Position, out currentNodeWorld); BoundingSphereD sphere = new BoundingSphereD() { Center = currentNodeWorld, Radius = m_autopilotShipBoundingRadius + 100f }; m_entitiesRepulse.Clear(); // use repulse list as prune/avoid is needed for CanTravelSegment MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, m_entitiesRepulse); if (m_entitiesRepulse.Count == 0 && BlueSkyReached(pnSet, currentNode, ref currentNodeWorld)) { return; } #if SHOW_REACHED ShowPosition(currentNode, SetName(pnSet)); #endif if (pnSet.NodeDistance < FindingSet.DefaultNodeDistance && pnSet.m_reachedNodes.Count % 10 == 0 && pnSet.m_openNodes.Count > 100) { Log.DebugLog("Reached: " + pnSet.m_reachedNodes.Count + ", trying with higher node distance"); pnSet.ChangeNodeDistance(false, m_canChangeCourse); return; } pnSet.CreatePathNode(ref currentNode, m_canChangeCourse); }
private void CheckHits() { for (int x = ActiveProjetiles.Count - 1; x >= 0; x--) { var p = ActiveProjetiles[x]; if ((int)p.State > 3) { continue; } if (p.Info.Ai.ProInMinCacheRange > 99999 && !p.Info.Ai.AccelChecked) { p.Info.Ai.ComputeAccelSphere(); } p.UseEntityCache = p.Info.Ai.AccelChecked && p.Info.DistanceTraveled <= p.Info.Ai.NearByEntitySphere.Radius && !p.Info.Ai.MarkedForClose; var triggerRange = p.Info.ConsumableDef.Const.EwarTriggerRange > 0 && !p.Info.EwarAreaPulse ? p.Info.ConsumableDef.Const.EwarTriggerRange : 0; var useEwarSphere = (triggerRange > 0 || p.Info.EwarActive) && p.Info.ConsumableDef.Const.Pulse; p.Beam = useEwarSphere ? new LineD(p.Position + (-p.Info.Direction * p.Info.ConsumableDef.Const.EwarTriggerRange), p.Position + (p.Info.Direction * p.Info.ConsumableDef.Const.EwarTriggerRange)) : new LineD(p.LastPosition, p.Position); if ((p.FieldTime <= 0 && p.State != ProjectileState.OneAndDone && p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr)) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.ConsumableDef.Const.DetonationRadius; var dInfo = p.Info.ConsumableDef.AreaEffect.Detonation; if (p.MoveToAndActivate || dInfo.DetonateOnEnd && p.Info.Age >= dInfo.MinArmingTime && (!dInfo.ArmOnlyOnHit || p.Info.ObjectsHit > 0)) { if (!p.UseEntityCache) { MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.MyEntityList, p.PruneQuery); } if (p.Info.System.TrackProjectile) { foreach (var lp in p.Info.Ai.LiveProjectile) { if (p.PruneSphere.Contains(lp.Position) != ContainmentType.Disjoint && lp != p.Info.Target.Projectile) { ProjectileHit(p, lp, p.Info.ConsumableDef.Const.CollisionIsLine, ref p.Beam); } } } p.State = ProjectileState.Detonate; if (p.EnableAv) { p.Info.AvShot.ForceHitParticle = true; } } else { p.State = ProjectileState.Detonate; } p.EarlyEnd = true; p.Info.Hit.SurfaceHit = p.Position; p.Info.Hit.LastHit = p.Position; } p.SphereCheck = false; p.LineCheck = false; if (p.MineSeeking && !p.MineTriggered) { p.SeekEnemy(); } else if (useEwarSphere) { if (p.Info.EwarActive) { p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0)); var currentRadius = p.Info.TriggerGrowthSteps < p.Info.ConsumableDef.Const.AreaEffectSize ? p.Info.TriggerMatrix.Scale.AbsMax() : p.Info.ConsumableDef.Const.AreaEffectSize; if (p.PruneSphere.Radius < currentRadius) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = currentRadius; } } else { p.PruneSphere = new BoundingSphereD(p.Position, triggerRange); } if (p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint) { p.SphereCheck = true; } } else if (p.Info.ConsumableDef.Const.CollisionIsLine) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.ConsumableDef.Const.CollisionSize; if (p.Info.ConsumableDef.Const.IsBeamWeapon || p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint) { p.LineCheck = true; } } else { p.SphereCheck = true; p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0)); if (p.PruneSphere.Radius < p.Info.ConsumableDef.Const.CollisionSize) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.ConsumableDef.Const.CollisionSize; } } } var apCount = ActiveProjetiles.Count; var minCount = Session.Settings.Enforcement.ServerOptimizations ? 96 : 99999; var stride = apCount < minCount ? 100000 : 48; MyAPIGateway.Parallel.For(0, apCount, i => { var p = ActiveProjetiles[i]; if (p.SphereCheck) { if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.System.Session.Tick60) { p.CheckForNearVoxel(60); } if (!p.UseEntityCache) { MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.MyEntityList, p.PruneQuery); } } else if (p.LineCheck) { if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.System.Session.Tick60) { p.CheckForNearVoxel(60); } if (!p.UseEntityCache) { MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref p.Beam, p.MySegmentList, p.PruneQuery); } } p.CheckType = p.UseEntityCache && p.SphereCheck ? CheckTypes.CachedSphere : p.UseEntityCache ? CheckTypes.CachedRay : p.SphereCheck ? CheckTypes.Sphere : CheckTypes.Ray; if (p.Info.Target.IsProjectile || p.UseEntityCache && p.Info.Ai.NearByEntityCache.Count > 0 || p.CheckType == CheckTypes.Ray && p.MySegmentList.Count > 0 || p.CheckType == CheckTypes.Sphere && p.MyEntityList.Count > 0) { ValidateHits.Add(p); } }, stride); ValidateHits.ApplyAdditions(); }
/// <summary> /// Override this function to set custom update behaviour. /// Call base at first because it queries objects if DoQuery is set. /// </summary> protected virtual void UpdateInternal() { if (DoQuery) { m_queryResult.Clear(); switch (m_triggerType) { case TriggerType.AABB: MyGamePruningStructure.GetTopMostEntitiesInBox(ref m_AABB, m_queryResult); break; case TriggerType.Sphere: MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref m_boundingSphere, m_queryResult); break; default: throw new ArgumentOutOfRangeException(); } for (int index = 0; index < m_queryResult.Count;) { var result = m_queryResult[index]; if (!QueryEvaluator(result)) { m_queryResult.RemoveAtFast(index); } else { switch (m_triggerType) { case TriggerType.AABB: if (!m_AABB.Intersects(m_queryResult[index].PositionComp.WorldAABB)) { m_queryResult.RemoveAtFast(index); } else { index++; } break; case TriggerType.Sphere: if (!m_boundingSphere.Intersects(m_queryResult[index].PositionComp.WorldAABB)) { m_queryResult.RemoveAtFast(index); } else { index++; } break; default: index++; break; } } } } }
private bool CalculateSafePositionAndSpawn(bool keepOriginalLocation, Vector3D Target) { //This has to be ran on the main game thread! if (keepOriginalLocation) { var sphere = FindBoundingSphere(_grids); sphere.Center = Target; List <MyEntity> entities = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities); bool PotentialGrids = false; foreach (var entity in entities) { if (entity is MyCubeGrid) { PotentialGrids = true; _Response.Respond("There are potentially other grids in the way. Attempting to spawn around the location to avoid collisions."); break; } } if (PotentialGrids) { var pos = FindPastePosition(Target); if (!pos.HasValue) { _Response.Respond("No free spawning zone found! Stopping load!"); return(false); } if (!UpdateGridsPosition(pos.Value)) { _Response.Respond("The File to be imported does not seem to be compatible with the server!"); return(false); } else { return(true); } } else { return(true); } } //Everything else is loading for near point if (!keepOriginalLocation) { /* Where do we want to paste the grids? Lets find out. */ var pos = FindPastePosition(Target); if (pos == null) { _Response.Respond("No free spawning zone found! Stopping load!"); return(false); } var newPosition = pos.Value; /* Update GridsPosition if that doesnt work get out of here. */ if (!UpdateGridsPosition(newPosition)) { _Response.Respond("The File to be imported does not seem to be compatible with the server!"); return(false); } } return(true); }
public static bool LoadShipBlueprint(MyObjectBuilder_ShipBlueprintDefinition shipBlueprint, Vector3D playerPosition, bool keepOriginalLocation, long steamID, string Name, CommandContext context = null, bool force = false) { var grids = shipBlueprint.CubeGrids; if (grids == null || grids.Length == 0) { Log.Warn("No grids in blueprint!"); if (context != null) { context.Respond("No grids in blueprint!"); } return(false); } foreach (var grid in grids) { foreach (MyObjectBuilder_CubeBlock block in grid.CubeBlocks) { long ownerID = AlliancePlugin.GetIdentityByNameOrId(steamID.ToString()).IdentityId; block.Owner = ownerID; block.BuiltBy = ownerID; } } List <MyObjectBuilder_EntityBase> objectBuilderList = new List <MyObjectBuilder_EntityBase>(grids.ToList()); if (!keepOriginalLocation) { /* Where do we want to paste the grids? Lets find out. */ var pos = FindPastePosition(grids, playerPosition); if (pos == null) { Log.Warn("No free Space found!"); if (context != null) { context.Respond("No free space available!"); } return(false); } var newPosition = pos.Value; /* Update GridsPosition if that doesnt work get out of here. */ if (!UpdateGridsPosition(grids, newPosition)) { if (context != null) { context.Respond("The File to be imported does not seem to be compatible with the server!"); } return(false); } Sandbox.Game.Entities.Character.MyCharacter player = MySession.Static.Players.GetPlayerByName(AlliancePlugin.GetIdentityByNameOrId(steamID.ToString()).DisplayName).Character; MyGps gps = CreateGps(pos.Value, Color.LightGreen, 60, Name); MyGpsCollection gpsCollection = (MyGpsCollection)MyAPIGateway.Session?.GPS; MyGps gpsRef = gps; long entityId = 0L; entityId = gps.EntityId; gpsCollection.SendAddGps(player.GetPlayerIdentityId(), ref gpsRef, entityId, true); } else if (!force) { var sphere = FindBoundingSphere(grids); var position = grids[0].PositionAndOrientation.Value; sphere.Center = position.Position; List <MyEntity> entities = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities); foreach (var entity in entities) { if (entity is MyCubeGrid) { if (context != null) { context.Respond("There are potentially other grids in the way. If you are certain is free you can set 'force' to true!"); } return(false); } } } /* Stop grids */ foreach (var grid in grids) { grid.AngularVelocity = new SerializableVector3(); grid.LinearVelocity = new SerializableVector3(); Random random = new Random(); } /* Remapping to prevent any key problems upon paste. */ MyEntities.RemapObjectBuilderCollection(objectBuilderList); bool hasMultipleGrids = objectBuilderList.Count > 1; if (!hasMultipleGrids) { foreach (var ob in objectBuilderList) { MyEntities.CreateFromObjectBuilderParallel(ob, true); } } else { MyEntities.Load(objectBuilderList, out _); } return(true); }
private void CheckHits() { foreach (var p in ActiveProjetiles) { p.Miss = false; if (!p.Active || (int)p.State > 3) { continue; } var triggerRange = p.Info.AmmoDef.Const.EwarTriggerRange > 0 && !p.Info.TriggeredPulse ? p.Info.AmmoDef.Const.EwarTriggerRange : 0; var useEwarSphere = triggerRange > 0 || p.Info.EwarActive; p.Beam = useEwarSphere ? new LineD(p.Position + (-p.Info.Direction * p.Info.AmmoDef.Const.EwarTriggerRange), p.Position + (p.Info.Direction * p.Info.AmmoDef.Const.EwarTriggerRange)) : new LineD(p.LastPosition, p.Position); if ((p.FieldTime <= 0 && p.State != ProjectileState.OneAndDone && p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr)) { var dInfo = p.Info.AmmoDef.AreaEffect.Detonation; p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = dInfo.DetonationRadius; if (p.MoveToAndActivate || dInfo.DetonateOnEnd && (!dInfo.ArmOnlyOnHit || p.Info.ObjectsHit > 0)) { MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.CheckList, p.PruneQuery); for (int i = 0; i < p.CheckList.Count; i++) { p.SegmentList.Add(new MyLineSegmentOverlapResult <MyEntity> { Distance = 0, Element = p.CheckList[i] }); } if (p.Info.System.TrackProjectile) { foreach (var lp in p.Info.Ai.LiveProjectile) { if (p.PruneSphere.Contains(lp.Position) != ContainmentType.Disjoint && lp != p.Info.Target.Projectile) { ProjectileHit(p, lp, p.Info.AmmoDef.Const.CollisionIsLine, ref p.Beam); } } } p.CheckList.Clear(); p.State = ProjectileState.Detonate; p.ForceHitParticle = true; } else { p.State = ProjectileState.Detonate; } p.Hit.HitPos = p.Position; } var sphere = false; var line = false; if (p.MineSeeking && !p.MineTriggered) { p.SeekEnemy(); } else if (useEwarSphere) { if (p.Info.EwarActive) { p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0)); var currentRadius = p.Info.TriggerGrowthSteps < p.Info.AmmoDef.Const.AreaEffectSize ? p.Info.TriggerMatrix.Scale.AbsMax() : p.Info.AmmoDef.Const.AreaEffectSize; if (p.PruneSphere.Radius < currentRadius) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = currentRadius; } } else { p.PruneSphere = new BoundingSphereD(p.Position, triggerRange); } if (p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint) { sphere = true; } } else if (p.Info.AmmoDef.Const.CollisionIsLine) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.AmmoDef.Const.CollisionSize; if (p.Info.AmmoDef.Const.IsBeamWeapon || p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint) { line = true; } } else { sphere = true; p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0)); if (p.PruneSphere.Radius < p.Info.AmmoDef.Const.CollisionSize) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.AmmoDef.Const.CollisionSize; } } if (sphere) { if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.Ai.Session.Tick60) { p.CheckForNearVoxel(60); } MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.CheckList, p.PruneQuery); for (int i = 0; i < p.CheckList.Count; i++) { p.SegmentList.Add(new MyLineSegmentOverlapResult <MyEntity> { Distance = 0, Element = p.CheckList[i] }); } p.CheckList.Clear(); } else if (line) { if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.Ai.Session.Tick60) { p.CheckForNearVoxel(60); } MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref p.Beam, p.SegmentList, p.PruneQuery); } if (p.Info.Target.IsProjectile || p.SegmentList.Count > 0) { ValidateHits.Add(p); continue; } p.Miss = true; p.Info.HitList.Clear(); } }
private bool CheckEnemyDistance(LoadType LoadingAtSavePoint, Vector3D Position = new Vector3D()) { if (LoadingAtSavePoint == LoadType.ForceLoadMearPlayer) { Position = PlayerPosition; } MyFaction PlayersFaction = MySession.Static.Factions.GetPlayerFaction(IdentityID); bool EnemyFoundFlag = false; if (Config.DistanceCheck > 0) { //Check enemy location! If under limit return! foreach (MyPlayer P in MySession.Static.Players.GetOnlinePlayers()) { if (P.Character == null || P.Character.MarkedForClose) { continue; } Vector3D Pos; if (P.Character.IsUsing is MyCryoChamber || P.Character.IsUsing is MyCockpit) { Pos = (P.Character.IsUsing as MyCockpit).PositionComp.GetPosition(); } else { Pos = P.GetPosition(); } long PlayerID = P.Identity.IdentityId; if (PlayerID == 0L) { continue; } if (PlayerID == IdentityID) { continue; } MyFaction TargetPlayerFaction = MySession.Static.Factions.GetPlayerFaction(PlayerID); if (PlayersFaction != null && TargetPlayerFaction != null) { if (PlayersFaction.FactionId == TargetPlayerFaction.FactionId) { continue; } //Neutrals count as allies not friends for some reason MyRelationsBetweenFactions Relation = MySession.Static.Factions.GetRelationBetweenFactions(PlayersFaction.FactionId, TargetPlayerFaction.FactionId).Item1; if (Relation == MyRelationsBetweenFactions.Neutral || Relation == MyRelationsBetweenFactions.Friends) { continue; } } if (Vector3D.Distance(Position, Pos) == 0) { continue; } if (Vector3D.Distance(Position, Pos) <= Config.DistanceCheck) { Chat?.Respond("Unable to load grid! Enemy within " + Config.DistanceCheck + "m!"); GpsSender.SendGps(Position, "Failed Hangar Load! (Enemy nearby)", IdentityID); EnemyFoundFlag = true; break; } } } if (Config.GridDistanceCheck > 0 && Config.GridCheckMinBlock > 0 && EnemyFoundFlag == false) { BoundingSphereD SpawnSphere = new BoundingSphereD(Position, Config.GridDistanceCheck); List <MyEntity> entities = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref SpawnSphere, entities); //This is looping through all grids in the specified range. If we find an enemy, we need to break and return/deny spawning foreach (MyCubeGrid Grid in entities.OfType <MyCubeGrid>()) { if (Grid == null || Grid.MarkedForClose) { continue; } if (Grid.BigOwners.Count <= 0 || Grid.CubeBlocks.Count < Config.GridCheckMinBlock) { continue; } if (Grid.BigOwners.Contains(IdentityID)) { continue; } //if the player isnt big owner, we need to scan for faction mates bool FoundAlly = true; foreach (long Owner in Grid.BigOwners) { MyFaction TargetPlayerFaction = MySession.Static.Factions.GetPlayerFaction(Owner); if (PlayersFaction != null && TargetPlayerFaction != null) { if (PlayersFaction.FactionId == TargetPlayerFaction.FactionId) { continue; } MyRelationsBetweenFactions Relation = MySession.Static.Factions.GetRelationBetweenFactions(PlayersFaction.FactionId, TargetPlayerFaction.FactionId).Item1; if (Relation == MyRelationsBetweenFactions.Enemies) { FoundAlly = false; break; } } else { FoundAlly = false; break; } } if (!FoundAlly) { //Stop loop Chat?.Respond("Unable to load grid! Enemy within " + Config.GridDistanceCheck + "m!"); GpsSender.SendGps(Position, "Failed Hangar Load! (Enemy nearby)", IdentityID); EnemyFoundFlag = true; break; } } } return(!EnemyFoundFlag); }
/// <summary> /// Test if it is safe for the grid to rotate. /// </summary> /// <param name="axis">Normalized axis of rotation in world space.</param> /// <returns>True iff the path is clear.</returns> private bool in_TestRotate(Vector3 axis) { IMyCubeGrid myGrid = m_block.CubeGrid; Vector3 centreOfMass = myGrid.Physics.CenterOfMassWorld; float longestDim = myGrid.GetLongestDim(); // calculate height Matrix toMyLocal = myGrid.WorldMatrixNormalizedInv; Vector3 myLocalCoM = Vector3.Transform(centreOfMass, toMyLocal); Vector3 myLocalAxis = Vector3.Transform(axis, toMyLocal.GetOrientation()); Vector3 myLocalCentre = myGrid.LocalAABB.Center; // CoM may not be on ship (it now considers mass from attached grids) Ray upper = new Ray(myLocalCentre + myLocalAxis * longestDim * 2f, -myLocalAxis); float? upperBound = myGrid.LocalAABB.Intersects(upper); if (!upperBound.HasValue) { Log.AlwaysLog("Math fail, upperBound does not have a value", Logger.severity.FATAL); } Ray lower = new Ray(myLocalCentre - myLocalAxis * longestDim * 2f, myLocalAxis); float?lowerBound = myGrid.LocalAABB.Intersects(lower); if (!lowerBound.HasValue) { Log.AlwaysLog("Math fail, lowerBound does not have a value", Logger.severity.FATAL); } //Log.DebugLog("LocalAABB: " + myGrid.LocalAABB + ", centre: " + myLocalCentre + ", axis: " + myLocalAxis + ", longest dimension: " + longestDim + ", upper ray: " + upper + ", lower ray: " + lower); float height = longestDim * 4f - upperBound.Value - lowerBound.Value; float furthest = 0f; foreach (IMyCubeGrid grid in AttachedGrid.AttachedGrids(myGrid, Attached.AttachedGrid.AttachmentKind.Physics, true)) { CubeGridCache cache = CubeGridCache.GetFor(grid); if (cache == null) { return(false); } foreach (Vector3I cell in cache.OccupiedCells()) { Vector3 rejection = Vector3.Reject(cell * myGrid.GridSize, myLocalAxis); float cellDistSquared = Vector3.DistanceSquared(myLocalCoM, rejection); if (cellDistSquared > furthest) { furthest = cellDistSquared; } } } float length = (float)Math.Sqrt(furthest) + myGrid.GridSize; //Log.DebugLog("height: " + height + ", length: " + length); BoundingSphereD surroundingSphere = new BoundingSphereD(centreOfMass, Math.Max(length, height) * MathHelper.Sqrt2); m_obstructions.Clear(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref surroundingSphere, m_obstructions); LineSegment axisSegment = new LineSegment(); m_closestPlanet = null; foreach (MyEntity entity in m_collector.Invoke(m_obstructions)) { if (entity is IMyVoxelBase) { IMyVoxelMap voxel = entity as IMyVoxelMap; if (voxel != null) { if (voxel.GetIntersectionWithSphere(ref surroundingSphere)) { Log.DebugLog("Too close to " + voxel.getBestName() + ", CoM: " + centreOfMass.ToGpsTag("Centre of Mass") + ", required distance: " + surroundingSphere.Radius); ObstructingEntity = voxel; return(false); } continue; } if (m_closestPlanet == null) { MyPlanet planet = entity as MyPlanet; if (planet == null) { continue; } double distToPlanetSq = Vector3D.DistanceSquared(centreOfMass, planet.PositionComp.GetPosition()); if (distToPlanetSq < planet.MaximumRadius * planet.MaximumRadius) { m_closestPlanet = planet; if (m_planetObstruction) { Log.DebugLog("planet blocking"); ObstructingEntity = m_closestPlanet; return(false); } } } continue; } IMyCubeGrid grid = entity as IMyCubeGrid; if (grid != null) { Matrix toLocal = grid.WorldMatrixNormalizedInv; Vector3 localAxis = Vector3.Transform(axis, toLocal.GetOrientation()); Vector3 localCentre = Vector3.Transform(centreOfMass, toLocal); axisSegment.From = localCentre - localAxis * height; axisSegment.To = localCentre + localAxis * height; CubeGridCache cache = CubeGridCache.GetFor(grid); if (cache == null) { return(false); } foreach (Vector3I cell in cache.OccupiedCells()) { if (axisSegment.PointInCylinder(length, cell * grid.GridSize)) { Log.DebugLog("axis segment: " + axisSegment.From + " to " + axisSegment.To + ", radius: " + length + ", hit " + grid.nameWithId() + " at " + cell); ObstructingEntity = grid; return(false); } } continue; } Log.DebugLog("No tests for object: " + entity.getBestName(), Logger.severity.INFO); ObstructingEntity = entity; return(false); } MyAPIGateway.Utilities.TryInvokeOnGameThread(TestPlanet); ObstructingEntity = null; return(true); }
private bool LoadShipBlueprint(MyObjectBuilder_ShipBlueprintDefinition shipBlueprint, Vector3D playerPosition, bool keepOriginalLocation, Chat chat, bool force = false) { var grids = shipBlueprint.CubeGrids; if (grids == null || grids.Length == 0) { Hangar.Debug("No grids in blueprint!"); chat.Respond("No grids in blueprint!"); return(false); } bool LoadNearPosition = false; //For loading in the same location ParallelSpawner Spawner = new ParallelSpawner(grids); var position = grids[0].PositionAndOrientation.Value; if (keepOriginalLocation) { var sphere = FindBoundingSphere(grids); sphere.Center = position.Position; List <MyEntity> entities = new List <MyEntity>(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities); foreach (var entity in entities) { if (entity is MyCubeGrid) { chat.Respond("There are potentially other grids in the way. Loading near the original point."); LoadNearPosition = true; } } if (!LoadNearPosition) { /* Remapping to prevent any key problems upon paste. */ MyEntities.RemapObjectBuilderCollection(grids); Spawner.Start(); return(true); } } /* * Everything else is loading for near player * * * */ /* Where do we want to paste the grids? Lets find out. */ var pos = FindPastePosition(grids, position.Position); if (pos == null) { Hangar.Debug("No free Space found!"); chat.Respond("No free space available!"); return(false); } var newPosition = pos.Value; /* Update GridsPosition if that doesnt work get out of here. */ if (!UpdateGridsPosition(grids, newPosition)) { chat.Respond("The File to be imported does not seem to be compatible with the server!"); return(false); } MyEntities.RemapObjectBuilderCollection(grids); Spawner.Start(); return(true); }