public LineSample(IMyCubeBlock reference, Vector3I forward3I) { Point = reference.GetPosition(); var forwardPoint = reference.CubeGrid.GridIntegerToWorld(forward3I); Direction = Vector3D.Normalize(forwardPoint - Point); }
void RepairDamaged(IMyCubeBlock block, IMyTerminalBlock nearestWelder) { if (activeRepairs.FirstOrDefault(x => x.Welder == nearestWelder && x.DamagedBlock == block) == null) //&& DistanceSquared(nearestWelder, block)<maximumWelderDamagedDistance { this.Echo(string.Format($"Welder: {nearestWelder.DisplayNameText}, {nearestWelder.EntityId}")); if (DistanceSquared(nearestWelder.GetPosition(), block.GetPosition()) < maximumWelderDamagedDistance) { try { nearestWelder.ApplyAction("OnOff_On"); } catch (Exception ex) { Echo(ex.Message); } activeRepairs.Add(new MyRepairInfo(nearestWelder, block, DistanceSquared(nearestWelder, block))); } else { Echo("Distance to big " + nearestWelder.DisplayNameText + ":" + DistanceSquared(nearestWelder, block).ToString()); } } }
internal bool IsAreaBeaconValid(IMyCubeBlock cubeBlock) { if (cubeBlock == null || !((IMyFunctionalBlock)cubeBlock).Enabled || !((IMyFunctionalBlock)cubeBlock).IsFunctional || !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(cubeBlock.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId))) { return(false); } float range = NaniteConstructionManager.Settings != null ? NaniteConstructionManager.Settings.AreaBeaconMaxDistanceFromNaniteFacility : 300f; foreach (var factory in m_constructionBlock.FactoryGroup) { if (IsEnabled(factory)) { if (Vector3D.Distance(cubeBlock.GetPosition(), factory.ConstructionBlock.GetPosition()) < range) { return(true); } foreach (var grid in factory.GridGroup.ToList()) { if (cubeBlock.CubeGrid == grid) { return(true); } } } } return(false); }
/// <summary> /// Calculates a transformation matrix to transform grid coordinates to world coordinates. /// </summary> /// <param name="blocks"></param> /// <returns></returns> public static VRageMath.Matrix toWorld(List <IMyCubeBlock> blocks) { if (blocks == null) { throw new Exception("The block list is null"); } if (blocks.Count < 3) { throw new Exception("Need at least 3 blocks."); } IMyCubeBlock origin = blocks[0]; VRageMath.Vector3 localCoord = origin.Position; // first basis vector VRageMath.Vector3 u = blocks[1].Position - localCoord; // second basis vector int vIndex = 2; VRageMath.Vector3 v = blocks[vIndex].Position - localCoord; while (u.Dot(v) * u.Dot(v) == u.LengthSquared() * v.LengthSquared() && vIndex < blocks.Count) { v = blocks[++vIndex].Position - localCoord; } if (u.Dot(v) * u.Dot(v) == u.LengthSquared() + v.LengthSquared()) { throw new Exception("All blocks are linear dependent => It's not possible to calculate a transformation matrix."); } debug.Append("choose: ").Append(u).Append(v).AppendLine(); VRageMath.Matrix localBasis = VRageMath.Matrix.CreateWorld(localCoord, u, v); VRageMath.Vector3 worldCoord = origin.GetPosition(); // world basis depending on the local bases (same coordinates) VRageMath.Vector3 ug = blocks[1].GetPosition() - worldCoord; VRageMath.Vector3 vg = blocks[vIndex].GetPosition() - worldCoord; VRageMath.Matrix worldBasis = VRageMath.Matrix.CreateWorld(worldCoord, ug, vg); VRageMath.Matrix inverseLocalBasis; // if local basis is orthogonal, take the transposed matrix, because then // the transposed and the inverse matrix are the same and it's obviously // easier to get the transposed matrix. if (VRageMath.Vector3.ArePerpendicular(ref u, ref v)) { inverseLocalBasis = VRageMath.Matrix.Transpose(localBasis); } else { inverseLocalBasis = VRageMath.Matrix.Invert(localBasis); } return(inverseLocalBasis * worldBasis); }
public bool IsProtecting(Vector3D postion) { if (((IMyFunctionalBlock)CubeBlock).IsWorking && ((IMyFunctionalBlock)CubeBlock).IsFunctional) { return(Math.Pow(GetRadius(), 2) > (CubeBlock.GetPosition() - postion).LengthSquared()); } return(false); }
public void SetLauncherReference(IMyCubeBlock launcherReference, Base6Directions.Direction direction = Base6Directions.Direction.Forward) { LauncherReferencePoint = launcherReference.GetPosition(); var forward3I = launcherReference.Position + Base6Directions.GetIntVector(launcherReference.Orientation.TransformDirection(direction)); var forwardPoint = launcherReference.CubeGrid.GridIntegerToWorld(forward3I); LauncherReferenceDirection = Vector3D.Normalize(forwardPoint - LauncherReferencePoint); }
/// <summary> /// Calculates a transformation matrix to transform grid coordinates to world coordinates. /// </summary> /// <param name="blocks"></param> /// <returns></returns> public static VRageMath.Matrix ToWorld(List <IMyCubeBlock> blocks) { if (blocks == null) { throw new Exception("The block list is null"); } if (blocks.Count < 3) { throw new Exception("Need at least 3 blocks."); } IMyCubeBlock origin = blocks[0]; VRageMath.Vector3 localCoord = origin.Position; // first basis vector VRageMath.Vector3 u = blocks[1].Position - localCoord; // second basis vector int vIndex = 2; VRageMath.Vector3 v = blocks[vIndex].Position - localCoord; // TODO use an epsilon value instead of 0, because of the precision error of floating point multiplication. while (u.Dot(v) == 0 && vIndex < blocks.Count) { v = blocks[++vIndex].Position - localCoord; } if (u.Dot(v) == 0) { throw new Exception("All blocks are linear dependent => It's not possible to calculate a transformation matrix."); } VRageMath.Matrix localBasis = VRageMath.Matrix.CreateWorld(localCoord, u, v); VRageMath.Vector3 worldCoord = origin.GetPosition(); // world basis depending on the local bases (same coordinates) VRageMath.Vector3 ug = blocks[1].GetPosition() - worldCoord; VRageMath.Vector3 vg = blocks[vIndex].GetPosition() - worldCoord; VRageMath.Matrix worldBasis = VRageMath.Matrix.CreateWorld(worldCoord, ug, vg); VRageMath.Matrix inverseLocalBasis; // if local basis is orthogonal, take the transposed matrix, because then // the transposed and the inverse matrix are the same and it's obviously // easier to get the transposed matrix. if (VRageMath.Vector3.ArePerpendicular(ref u, ref v)) { inverseLocalBasis = VRageMath.Matrix.Transpose(localBasis); } else { inverseLocalBasis = VRageMath.Matrix.Invert(localBasis); } return(inverseLocalBasis * worldBasis); }
public static bool EntityOver(IMyCubeBlock block, MyDetectedEntityInfo entity) { Vector3D center = block.GetPosition(); Vector3D min = center - new Vector3D(1.25); Vector3D max = center + new Vector3D(1.25); return(VectorCompare(entity.Position, min, new DoubleComparisons.GreaterOrEqual()) && VectorCompare(entity.Position, max, new DoubleComparisons.LessOrEqual())); }
public static void doShowoff(IMyCubeBlock showoff, IEnumerator <LastSeen> toDisplay, int toDisplayCount) { LinkedList <Ingame.IMyTextPanel> textPanels = findTextPanel(showoff); if (textPanels == null) { return; } log("building toDisplay", "findTextPanel()", Logger.severity.TRACE); Vector3D myPos = showoff.GetPosition(); List <sortableLastSeen> sortableSeen = new List <sortableLastSeen>(); while (toDisplay.MoveNext()) { IMyCubeGrid grid = toDisplay.Current.Entity as IMyCubeGrid; if (grid == null || AttachedGrids.isGridAttached(grid, showoff.CubeGrid)) { continue; } IMyCubeBlockExtensions.Relations relations = showoff.getRelationsTo(grid, IMyCubeBlockExtensions.Relations.Enemy).mostHostile(); sortableSeen.Add(new sortableLastSeen(myPos, toDisplay.Current, relations)); } sortableSeen.Sort(); int count = 0; StringBuilder displayText = new StringBuilder(); foreach (sortableLastSeen sortable in sortableSeen) { displayText.Append(sortable.ToStringBuilder(count++)); if (count >= 50) { break; } } string displayString = displayText.ToString(); foreach (Ingame.IMyTextPanel panel in textPanels) { log("writing to panel: " + panel.DisplayNameText, "findTextPanel()", Logger.severity.TRACE); panel.WritePublicText(displayString); if (panel.GetPublicTitle() != publicTitle) { panel.WritePublicTitle(publicTitle); panel.AddImageToSelection(radarId); panel.ShowTextureOnScreen(); } } }
private void CheckAreaBeacons(List <IMyCubeGrid> NaniteGridGroup) { foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x.Value is NaniteAreaBeacon).ToList()) { IMyCubeBlock cubeBlock = (IMyCubeBlock)beaconBlock.Value.BeaconBlock; if (!IsAreaBeaconValid(cubeBlock)) { continue; } var item = beaconBlock.Value as NaniteAreaBeacon; if (!item.Settings.AllowDeconstruction) { continue; } HashSet <IMyEntity> entities = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entities); foreach (var entity in entities) { var grid = entity as IMyCubeGrid; if (grid != null && grid.Physics != null && grid.Physics.AngularVelocity.Length() == 0f && grid.Physics.LinearVelocity.Length() == 0f && m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(grid)) == null && !MyAPIGateway.GridGroups.GetGroup(grid, GridLinkTypeEnum.Physical).Contains(cubeBlock.CubeGrid) && (grid.GetPosition() - cubeBlock.GetPosition()).LengthSquared() < m_maxDistance * m_maxDistance && item.IsInsideBox(grid.WorldAABB, false)) { NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(grid); m_validBeaconedGrids.Add(deconstruct); CreateGridStack(NaniteGridGroup, deconstruct, (MyCubeGrid)grid, null); if (!m_areaTargetBlocks.ContainsKey(grid)) { m_areaTargetBlocks.Add(grid, item); } else { m_areaTargetBlocks[grid] = item; } foreach (var block in deconstruct.RemoveList) { if (!PotentialTargetList.Contains(block)) { PotentialTargetList.Add(block); } } } } } }
private void CheckAreaBeacons() { foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteAreaBeacon)) { IMyCubeBlock cubeBlock = beaconBlock.BeaconBlock; //MyRelationsBetweenPlayerAndBlock relation = cubeBlock.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId); //if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership))) // continue; if (!((IMyFunctionalBlock)cubeBlock).Enabled) { continue; } var item = beaconBlock as NaniteAreaBeacon; if (!item.Settings.AllowRepair) { continue; } HashSet <IMyEntity> entities = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entities); foreach (var entity in entities) { var grid = entity as IMyCubeGrid; if (grid == null) { continue; } if (grid.Physics == null) { continue; } if ((grid.GetPosition() - cubeBlock.GetPosition()).LengthSquared() < m_maxDistance * m_maxDistance) { foreach (IMySlimBlock block in ((MyCubeGrid)grid).GetBlocks()) { BoundingBoxD blockbb; block.GetWorldBoundingBox(out blockbb); if (item.IsInsideBox(blockbb)) { AddPotentialBlock(block, true, item); } } } } } }
void GetWelsersAndStartRepair(IMyCubeBlock block) { List <IMyTerminalBlock> allWelders = new List <IMyTerminalBlock>(); this.GridTerminalSystem.GetBlocksOfType <IMyShipWelder>(allWelders); this.Echo(string.Format($"Damaged block: {block.DisplayNameText}, {block.EntityId}")); var nearestWelders = allWelders.OrderBy(welder => DistanceSquared(block.GetPosition(), welder.GetPosition())).Take(numberOfWeldersToFindNearest).ToList(); nearestWelders.ForEach(welder => { RepairDamaged(block, welder); } ); }
public override Vector3D GetPosition() { if (!m_accel && !Entity.Closed && (m_block == null || !m_block.Closed)) { m_accel = Vector3.DistanceSquared(m_lastSeen.Entity.Physics.LinearVelocity, m_lastSeen.LastKnownVelocity) > 1f; if (!m_accel) { m_lastPostion = m_block != null?m_block.GetPosition() : m_lastSeen.Entity.GetCentre(); m_lastPositionUpdate = Globals.ElapsedTime; return(m_lastPostion); } } return(m_lastPostion + m_lastSeen.GetLinearVelocity() * (float)(Globals.ElapsedTime - m_lastPositionUpdate).TotalSeconds); }
internal void CheckConstructionOrProjectionAreaBeacons(bool isProjection = false) { foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x.Value is NaniteAreaBeacon).ToList()) { IMyCubeBlock cubeBlock = beaconBlock.Value.BeaconBlock; if (!IsAreaBeaconValid(cubeBlock)) { continue; } var item = beaconBlock.Value as NaniteAreaBeacon; if ((isProjection && !item.Settings.AllowProjection) || !item.Settings.AllowRepair) { continue; } float range = NaniteConstructionManager.Settings != null ? NaniteConstructionManager.Settings.ConstructionMaxBeaconDistance : 300f; if (isProjection) { range = NaniteConstructionManager.Settings != null ? NaniteConstructionManager.Settings.ProjectionMaxBeaconDistance : 300f; } HashSet <IMyEntity> entities = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entities); foreach (var entity in entities) { var grid = entity as IMyCubeGrid; if (grid == null || (grid.GetPosition() - cubeBlock.GetPosition()).LengthSquared() >= range * range) { continue; } foreach (IMySlimBlock block in ((MyCubeGrid)grid).GetBlocks()) { BoundingBoxD blockbb; block.GetWorldBoundingBox(out blockbb, true); if (item.IsInsideBox(blockbb)) { m_constructionBlock.ScanBlocksCache.Add(new BlockTarget(block, true, item)); } } } } }
/// <summary> /// Test the path for obstructions /// </summary> /// <exception cref="InterruptException">If interrupted</exception> /// I considered keeping track of the closest entity, in the event there was no obstruction. This would have been, at best, unreliable due to initial AABB test. public IMyEntity TestPath(Vector3D worldDestination, IMyCubeBlock navigationBlock, bool IgnoreAsteroids, out Vector3?pointOfObstruction, IMyCubeGrid DestGrid) { worldDestination.throwIfNull_argument("destination"); worldDestination.throwIfNull_argument("navigationBlock"); Interrupt = false; this.NavigationBlock = navigationBlock; this.IgnoreAsteroids = IgnoreAsteroids; this.DestGrid = DestGrid; myLogger.debugLog("Test path to (world absolute) " + worldDestination, "TestPath()"); //myLogger.debugLog("destination (local) = " + worldDestination.getLocal(), "TestPath()"); //myLogger.debugLog("destination (nav block) = " + worldDestination.getBlock(navigationBlock), "TestPath()"); Vector3D Displacement = worldDestination - navigationBlock.GetPosition(); myLogger.debugLog("Displacement = " + Displacement, "TestPath()"); // entities in large AABB BoundingBoxD AtDest = myCubeGrid.WorldAABB.Translate(Displacement); ICollection <IMyEntity> offenders = EntitiesInLargeAABB(myCubeGrid.WorldAABB, AtDest); if (offenders.Count == 0) { myLogger.debugLog("AABB is empty", "TestPath()", Logger.severity.DEBUG); pointOfObstruction = null; return(null); } myLogger.debugLog("collected entities to test: " + offenders.Count, "TestPath()"); // sort offenders by distance offenders = SortByDistance(offenders); // set destination GridShapeProfiler myGridShape = GridShapeProfiler.getFor(myCubeGrid); //myLogger.debugLog("destination = " + worldDestination.getWorldAbsolute() + ", navigationBlock = " + navigationBlock.GetPosition(), "TestPath()"); myGridShape.SetDestination(RelativeVector3F.createFromWorldAbsolute(worldDestination, myCubeGrid), navigationBlock); myPath = myGridShape.myPath; myLogger.debugLog("got path from " + myPath.P0 + " to " + myPath.P1 + " with radius " + myPath.Radius, "TestPath()"); // test path return(TestEntities(offenders, myPath, myGridShape, out pointOfObstruction, this.DestGrid)); }
/// <remarks> /// <para>Targeting non-terminal blocks would cause confusion.</para> /// <para>Tiny blocks, such as sensors, shall be skipped.</para> /// <para>Open doors shall not be targeted.</para> /// </remarks> private bool TargetableBlock(IMyCubeBlock block, bool Disable) { if (!(block is IMyTerminalBlock)) { return(false); } if (block.Mass < 100) { return(false); } IMyDoor asDoor = block as IMyDoor; if (asDoor != null && asDoor.OpenRatio > 0.01) { return(false); } if (Disable && !block.IsWorking) { if (!block.IsFunctional || !Options.FlagSet(TargetingFlags.Functional)) { Log.TraceLog("disable: " + Disable + ", working: " + block.IsWorking + ", functional: " + block.IsFunctional + ", target functional: " + Options.FlagSet(TargetingFlags.Functional)); return(false); } } if (Blacklist.Contains(block.EntityId)) { Log.TraceLog("blacklisted: " + block.nameWithId()); return(false); } Vector3D position = block.GetPosition(); if (!CanRotateTo(ref position, block)) { Log.TraceLog("cannot face: " + block.nameWithId()); return(false); } return(true); }
private void CheckAreaBeacons() { foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteAreaBeacon)) { IMyCubeBlock cubeBlock = beaconBlock.BeaconBlock; if (!((IMyFunctionalBlock)cubeBlock).Enabled || !((IMyFunctionalBlock)cubeBlock).IsFunctional) { continue; } var item = beaconBlock as NaniteAreaBeacon; if (!item.Settings.AllowProjection) { continue; } HashSet <IMyEntity> entities = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entities); foreach (var entity in entities) { var grid = entity as IMyCubeGrid; if (grid == null) { continue; } if ((grid.GetPosition() - cubeBlock.GetPosition()).LengthSquared() < m_maxDistance * m_maxDistance) { foreach (IMySlimBlock block in ((MyCubeGrid)grid).GetBlocks()) { BoundingBoxD blockbb; block.GetWorldBoundingBox(out blockbb, true); if (item.IsInsideBox(blockbb)) { CheckBlockProjection(block); } } } } } }
/// <summary> /// Finds the best matching block ordered by distance(in metres) + time since last seen(in millis). /// </summary> /// <param name="bestMatchBlock"></param> /// <param name="blockContains"></param> /// <returns></returns> public bool findBestHostile(IMyCubeGrid grid, out IMyCubeBlock bestMatchBlock, string blockContains) { List <IMySlimBlock> collected = new List <IMySlimBlock>(); bestMatchBlock = null; double bestMatchDist = -1; grid.GetBlocks(collected, block => collect_findBestHostile(block, blockContains)); foreach (IMySlimBlock block in collected) { IMyCubeBlock Fatblock = block.FatBlock; double distance = owner.myGrid.WorldAABB.Distance(Fatblock.GetPosition()); if (bestMatchBlock == null || distance < bestMatchDist) // if better match { bestMatchBlock = Fatblock; bestMatchDist = distance; } } return(bestMatchBlock != null); }
Vector3D getPosRel(IMyCubeBlock anchor, Vector3I offset) { //1) Get world position Vector3D basePosition = anchor.GetPosition(); //2) Get world direction vectors Vector3D upVector = anchor.WorldMatrix.Up; Vector3D leftVector = anchor.WorldMatrix.Left; Vector3D backwardVector = anchor.WorldMatrix.Backward; //Relative distances int leftDistance = offset.X; int upDistance = offset.Y; int backDistance = offset.Z; //3) Calc target position Vector3D newPos = basePosition + upVector * upDistance + backwardVector * backDistance + leftVector * leftDistance; EchoF(@"base: {0}, up: {1}, left: {2}, back: {3}, LDist: {4}, UDist: {5}, BDist: {6}, NEW: {7}", basePosition, upVector, leftVector, backwardVector, leftDistance, upDistance, backDistance, newPos); return(newPos); }
/// <summary> /// How far long the line would the ship be able to travel? Uses a capsule derived from previously calculated path. /// </summary> /// <param name="canTravel">Line along which navigation block would travel</param> /// <remarks> /// Capsule only test because the ship will not be oriented correctly /// </remarks> /// <returns>distance from the destination that can be reached</returns> public float distanceCanTravel(Line canTravel) { Vector3D navBlockPos = NavigationBlock.GetPosition(); Vector3D DisplacementStart = canTravel.From - navBlockPos; Vector3D DisplacementEnd = canTravel.To - navBlockPos; BoundingBoxD atStart = myCubeGrid.WorldAABB.Translate(DisplacementStart); BoundingBoxD atDest = myCubeGrid.WorldAABB.Translate(DisplacementEnd); ICollection <IMyEntity> offenders = EntitiesInLargeAABB(atStart, atDest); if (offenders.Count == 0) { myLogger.debugLog("AABB is empty", "distanceCanTravel()"); return(0); } myLogger.debugLog("collected entities to test: " + offenders.Count, "TestPath()"); offenders = SortByDistance(offenders); //if (offenders.Count == 0) //{ // myLogger.debugLog("all offenders ignored", "distanceCanTravel()"); // return 0; //} //myLogger.debugLog("remaining after ignore list: " + offenders.Count, "TestPath()"); Capsule _path = new Capsule(canTravel.From, canTravel.To, myPath.Radius); Vector3? pointOfObstruction; IMyEntity obstruction = TestEntities(offenders, _path, null, out pointOfObstruction, DestGrid); if (obstruction == null) { myLogger.debugLog("no obstruction", "distanceCanTravel()"); return(0); } myLogger.debugLog("obstruction at " + pointOfObstruction + " distance from dest is " + Vector3.Distance(canTravel.To, (Vector3)pointOfObstruction), "distanceCanTravel()"); return(Vector3.Distance(canTravel.To, (Vector3)pointOfObstruction)); }
public static Vector3D GetCentre(this IMyEntity entity) { IMyCubeBlock block = entity as IMyCubeBlock; if (block != null) { return(block.GetPosition()); } MyPlanet planet = entity as MyPlanet; if (planet != null) { return(planet.WorldMatrix.Translation); } IMyVoxelBase asteroid = entity as IMyVoxelBase; if (asteroid != null) { return(asteroid.WorldAABB.Center); } return(Vector3D.Transform(entity.LocalAABB.Center, entity.WorldMatrix)); }
public bool SeeWeldPadInfo() { if (!Networking.IsPlayer) { return(false); } if (ThisPad.GetPlayerRelationToOwner() == MyRelationsBetweenPlayerAndBlock.Enemies) { return(false); } // doesn't quite work for ship with LG carrying a weldpad'd block //IMyShipController controlled = MyAPIGateway.Session.ControlledObject as IMyShipController; //if(controlled != null) //{ // if(!controlled.CanControlShip) // return false; // if(!MyAPIGateway.GridGroups.HasConnection(controlled.CubeGrid, ThisPad.CubeGrid, GridLinkTypeEnum.Mechanical)) // return false; // if(OtherPad != null && !MyAPIGateway.GridGroups.HasConnection(controlled.CubeGrid, OtherPad.CubeGrid, GridLinkTypeEnum.Mechanical)) // return false; //} //else { Vector3D camPos = MyAPIGateway.Session.Camera.WorldMatrix.Translation; Vector3D padPos = ThisPad.GetPosition(); if (Vector3D.DistanceSquared(camPos, padPos) > NotifyMaxDistanceSq) { return(false); } } return(true); }
// Explicit direction public LineSample(IMyCubeBlock reference, Vector3D direction) { Point = reference.GetPosition(); Direction = Vector3D.Normalize(direction); }
/// <remarks> /// <para>Targeting non-terminal blocks would cause confusion.</para> /// <para>Open doors should not be targeted.</para> /// </remarks> private bool TargetableBlock(IMyCubeBlock block, bool Disable) { if (!(block is IMyTerminalBlock)) return false; if (block.Mass < 100) return false; IMyDoor asDoor = block as IMyDoor; if (asDoor != null && asDoor.OpenRatio > 0.01) return false; if (Disable && !block.IsWorking) if (!block.IsFunctional || !Options.FlagSet(TargetingFlags.Functional)) return false; if (!CanRotateTo(block.GetPosition())) return false; return true; }
public void UpdateAfterSimulation() { if (myCubeBlock == null) { return; } //if (needToRelease) // lock_notMyUpdate.ReleaseExclusive(); //needToRelease = false; try { if (!myCubeBlock.IsWorking || myCubeBlock.Closed) { return; } if (updateCount % 100 == 0) // every 100 updates { if (updateCount == 1000) { myLogger.debugLog("update 1000", "UpdateAfterSimulation()"); reset(); return; } controlEnabled = myCubeBlock.DisplayNameText.Contains("[") && myCubeBlock.DisplayNameText.Contains("]"); TurretBase_CustomNameChanged(null); if (myAntenna == null || myAntenna.CubeBlock == null || !myAntenna.CubeBlock.canSendTo(myCubeBlock, true)) { //myLogger.debugLog("searching for attached antenna", "UpdateAfterSimulation10()"); myAntenna = null; foreach (Receiver antenna in RadioAntenna.registry) { if (antenna.CubeBlock.canSendTo(myCubeBlock, true)) { myLogger.debugLog("found attached antenna: " + antenna.CubeBlock.DisplayNameText, "UpdateAfterSimulation10()", Logger.severity.INFO); myAntenna = antenna; break; } } if (myAntenna == null) { foreach (Receiver antenna in LaserAntenna.registry) { if (antenna.CubeBlock.canSendTo(myCubeBlock, true)) { myLogger.debugLog("found attached antenna: " + antenna.CubeBlock.DisplayNameText, "UpdateAfterSimulation10()", Logger.severity.INFO); myAntenna = antenna; break; } } } //if (myAntenna == null) //myLogger.debugLog("did not find attached antenna", "UpdateAfterSimulation10()"); } MyObjectBuilder_TurretBase builder = myCubeBlock.getSlimObjectBuilder() as MyObjectBuilder_TurretBase; targetMissiles = builder.TargetMissiles; targetMeteors = MeteorsEnabled && builder.TargetMeteors; targetCharacters = builder.TargetCharacters; targetMoving = builder.TargetMoving; targetLargeGrids = builder.TargetLargeGrids; targetSmallGrids = builder.TargetSmallGrids; targetStations = builder.TargetStations; if (possibleTargets()) { if (CurrentState == State.NO_POSSIBLE) { myLogger.debugLog("now possible to target", "UpdateAfterSimulation()"); CurrentState = State.OFF; } } else if (CurrentState != State.NO_POSSIBLE) { myLogger.debugLog("no longer possible to target", "UpdateAfterSimulation()"); setNoTarget(); CurrentState = State.NO_POSSIBLE; } } // end if (updateCount % 100 == 0) if (CurrentState == State.NO_POSSIBLE) { return; } if (!controlEnabled) { if (CurrentState != State.OFF) { CurrentState = State.OFF; //myTurretBase.TrackTarget(null); myTurretBase.ResetTargetingToDefault(); } return; } if (CurrentState == State.OFF) { if (defaultTargetingAcquiredTarget) { setNoTarget(); } else { CurrentState = State.WAIT_DTAT; } } // Wait for default targeting to acquire a target. if (CurrentState == State.WAIT_DTAT) { if (updateCount % 10 == 0) { turretPosition = myCubeBlock.GetPosition(); MyObjectBuilder_TurretBase builder = myCubeBlock.getSlimObjectBuilder() as MyObjectBuilder_TurretBase; IMyEntity target; if (MyAPIGateway.Entities.TryGetEntityById(builder.Target, out target)) { if ((target is IMyCubeBlock || target is IMyMeteor) && canLase(target)) { defaultTargetingAcquiredTarget = true; setNoTarget(); myLogger.debugLog("default targeting acquired a target: " + target.getBestName(), "UpdateAfterSimulation()", Logger.severity.DEBUG); } } } return; } // start thread if (!queued && updateCount % 10 == 0) { queued = true; TurretThread.EnqueueAction(Update); } } catch (Exception e) { myLogger.log("Exception: " + e, "UpdateAfterSimulation10()", Logger.severity.ERROR); } finally { updateCount++; //needToRelease = true; //lock_notMyUpdate.AcquireExclusive(); } }
// Use the "forward" direction of the reference block public LineSample(IMyCubeBlock reference) { Point = reference.GetPosition(); Direction = reference.WorldMatrix.Forward; }
/// <summary> /// Gets the best block to target from a grid. /// </summary> /// <param name="grid">The grid to search</param> /// <param name="tType">Checked for destroy</param> /// <param name="target">The best block fromt the grid</param> /// <param name="distanceValue">The value assigned based on distance and position in blocksToTarget.</param> /// <remarks> /// <para>Decoy blocks will be given a distanceValue of the distance squared to weapon.</para> /// <para>Blocks from blocksToTarget will be given a distanceValue of the distance squared * (index + 1)^3.</para> /// <para>Other blocks will be given a distanceValue of the distance squared * (1e12).</para> /// </remarks> public bool GetTargetBlock(IMyCubeGrid grid, TargetType tType, out IMyCubeBlock target, out double distanceValue, bool doRangeTest = true) { Vector3D myPosition = ProjectilePosition(); CubeGridCache cache = CubeGridCache.GetFor(grid); target = null; distanceValue = double.MaxValue; if (cache == null) { return(false); } if (cache.TerminalBlocks == 0) { Log.TraceLog("no terminal blocks on grid: " + grid.DisplayName); return(false); } // get decoy block { foreach (IMyCubeBlock block in cache.BlocksOfType(typeof(MyObjectBuilder_Decoy))) { if (!TargetableBlock(block, true)) { continue; } double distanceSq = Vector3D.DistanceSquared(myPosition, block.GetPosition()); if (doRangeTest && distanceSq > Options.TargetingRangeSquared) { continue; } if (distanceSq < distanceValue && CanConsiderHostile(block)) { target = block; distanceValue = distanceSq; } } if (target != null) { Log.TraceLog("for type = " + tType + " and grid = " + grid.DisplayName + ", found a decoy block: " + target.DisplayNameText + ", distanceValue: " + distanceValue); return(true); } } // get block from blocksToTarget if (!Options.blocksToTarget.IsNullOrEmpty()) { int index = 0; IMyCubeBlock in_target = target; double in_distValue = distanceValue; foreach (MyDefinitionId[] ids in Options.listOfBlocks.IdGroups()) { index++; foreach (MyDefinitionId id in ids) { //Log.TraceLog("searching for blocks of type: " + id + ", count: " + cache.BlocksOfType(id).Count()); foreach (IMyCubeBlock block in cache.BlocksOfType(id)) { if (!TargetableBlock(block, true)) { continue; } double distSq = Vector3D.DistanceSquared(myPosition, block.GetPosition()); if (doRangeTest && distSq > Options.TargetingRangeSquared) { Log.TraceLog("out of range: " + block.nameWithId()); continue; } distSq *= index * index * index; if (distSq < in_distValue && CanConsiderHostile(block)) { in_target = block; in_distValue = distSq; } } } } target = in_target; distanceValue = in_distValue; if (target != null) // found a block from blocksToTarget { Log.TraceLog("for type = " + tType + " and grid = " + grid.DisplayName + ", target = " + target.DisplayNameText + ", distance = " + Vector3D.Distance(myPosition, target.GetPosition()) + ", distanceValue = " + distanceValue); return(true); } } // get any IMyTerminalBlock bool destroy = (tType & TargetType.Moving) != 0 || (tType & TargetType.Destroy) != 0; if (destroy || Options.blocksToTarget.IsNullOrEmpty()) { double closest = double.MaxValue; foreach (MyCubeBlock block in cache.AllCubeBlocks()) { if (block is IMyTerminalBlock && TargetableBlock(block, !destroy)) { double distanceSq = Vector3D.DistanceSquared(myPosition, block.PositionComp.GetPosition()); if (doRangeTest && distanceSq > Options.TargetingRangeSquared) { continue; } distanceSq *= 1e12; if (distanceSq < closest && CanConsiderHostile(block)) { target = block; distanceValue = distanceSq; } } } if (target != null) { Log.TraceLog("for type = " + tType + " and grid = " + grid.DisplayName + ", found a block: " + target.DisplayNameText + ", distanceValue = " + distanceValue); return(true); } } return(false); }
public override void ParallelUpdate(List <IMyCubeGrid> NaniteGridGroup, List <BlockTarget> gridBlocks) { try { // Add foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x.Value is NaniteBeaconDeconstruct)) { IMyCubeBlock item = (IMyCubeBlock)beaconBlock.Value.BeaconBlock; if (item == null || item.CubeGrid == null || !((IMyFunctionalBlock)item).Enabled || !((IMyFunctionalBlock)item).IsFunctional || NaniteGridGroup.Contains(item.CubeGrid) || !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId)) || m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(item.CubeGrid)) != null || !IsInRange(item.GetPosition(), m_maxDistance) ) { continue; } NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(item.CubeGrid); CreateGridStack(NaniteGridGroup, deconstruct, (MyCubeGrid)item.CubeGrid, (MyCubeBlock)item); m_validBeaconedGrids.Add(deconstruct); Logging.Instance.WriteLine($"[Deconstruction] Grid {item.CubeGrid.CustomName} queued for deconstruction", 1); foreach (var slimBlock in deconstruct.RemoveList) { if (slimBlock != null) { PotentialTargetList.Add(slimBlock); } } deconstruct.RemoveList.Clear(); } CheckAreaBeacons(NaniteGridGroup); if (PotentialTargetList.Count > 0) { foreach (IMySlimBlock item in PotentialTargetList.ToList()) { if (item == null || item.CubeGrid == null || item.CubeGrid.Closed || item.IsDestroyed || item.IsFullyDismounted || (item.FatBlock != null && item.FatBlock.Closed) || EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, item) > m_maxDistance) { PotentialTargetList.Remove(item); } } } else if (TargetList.Count == 0 && PotentialTargetList.Count == 0) { m_validBeaconedGrids.Clear(); } } catch (Exception e) { Logging.Instance.WriteLine($"Exception in NaniteDeconstructionTargets.ParallelUpdate:\n{e}"); } }
public override void CheckBeacons() { foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x.Value is NaniteBeaconProjection)) { IMyCubeBlock item = (IMyCubeBlock)beaconBlock.Value.BeaconBlock; if (item == null || !((IMyFunctionalBlock)item).Enabled || !((IMyFunctionalBlock)item).IsFunctional || !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId)) || !IsInRange(item.GetPosition(), m_maxDistance)) { continue; } List <IMySlimBlock> beaconBlocks = new List <IMySlimBlock>(); foreach (var grid in MyAPIGateway.GridGroups.GetGroup((IMyCubeGrid)item.CubeGrid, GridLinkTypeEnum.Physical)) { grid.GetBlocks(beaconBlocks); } foreach (var block in beaconBlocks) { m_constructionBlock.ScanBlocksCache.Add(new BlockTarget(block)); } } }
public static Vector3D GetCentre(this IMyCubeBlock block) { return(block.GetPosition()); }
public static double GetDistanceBetweenBlockAndSlimblock(IMyCubeBlock block, IMySlimBlock slimBlock) { return(Vector3D.Distance(block.GetPosition(), GetBlockPosition(slimBlock))); }
private void CheckAreaBeacons() { foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteAreaBeacon)) { IMyCubeBlock cubeBlock = (IMyCubeBlock)beaconBlock.BeaconBlock; if (!((IMyFunctionalBlock)cubeBlock).Enabled || !((IMyFunctionalBlock)cubeBlock).IsFunctional) { continue; } MyRelationsBetweenPlayerAndBlock relation = cubeBlock.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId); if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership))) { continue; } var item = beaconBlock as NaniteAreaBeacon; if (!item.Settings.AllowDeconstruction) { continue; } HashSet <IMyEntity> entities = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entities); foreach (var entity in entities) { var grid = entity as IMyCubeGrid; if (grid == null) { continue; } if (grid.Physics == null) { continue; } if (grid.Physics.AngularVelocity.Length() != 0f || grid.Physics.LinearVelocity.Length() != 0f) { continue; } if (m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(grid)) != null) { continue; } if (GridHelper.GetGridGroup(grid).Contains(cubeBlock.CubeGrid)) { continue; } if ((grid.GetPosition() - cubeBlock.GetPosition()).LengthSquared() < m_maxDistance * m_maxDistance) { if (item.IsInsideBox(grid.WorldAABB, false)) { NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(grid); m_validBeaconedGrids.Add(deconstruct); CreateGridStack(deconstruct, (MyCubeGrid)grid, null); if (!m_areaTargetBlocks.ContainsKey(grid)) { m_areaTargetBlocks.Add(grid, item); } else { m_areaTargetBlocks[grid] = item; } foreach (var block in deconstruct.RemoveList) { if (!PotentialTargetList.Contains(block)) { PotentialTargetList.Add(block); } } } } } } }