/// <summary> /// Get all the components that are in inventories on the autopilot ship. /// </summary> private void GetInventoryItems() { if (m_blocksWithInventory == null) { m_blocksWithInventory = new List <IMySlimBlock>(); m_controlBlock.CubeGrid.GetBlocks_Safe(m_blocksWithInventory, slim => slim.FatBlock != null && (slim.FatBlock as MyEntity).HasInventory); Log.DebugLog("blocks with inventory: " + m_blocksWithInventory.Count); } m_components_inventory.Clear(); foreach (IMySlimBlock slim in m_blocksWithInventory) { if (slim.FatBlock.Closed) { continue; } MyEntity asEntity = slim.FatBlock as MyEntity; int inventories = asEntity.InventoryCount; Log.DebugLog("searching " + inventories + " inventories of " + slim.FatBlock.DisplayNameText); for (int i = 0; i < inventories; i++) { List <MyPhysicalInventoryItem> allItems = null; MainLock.UsingShared(() => allItems = asEntity.GetInventory(i).GetItems()); foreach (MyPhysicalInventoryItem item in allItems) { if (item.Content.TypeId != typeof(MyObjectBuilder_Component)) { Log.DebugLog("skipping " + item.Content + ", not a component"); continue; } Log.DebugLog("item: " + item.Content.SubtypeName + ", amount: " + item.Amount); int amount = (int)item.Amount; if (amount < 1) { continue; } string name = item.Content.SubtypeName; int count; if (!m_components_inventory.TryGetValue(name, out count)) { count = 0; } count += amount; m_components_inventory[name] = count; } } } }
private void Update() { try { if (!controlEnabled) { return; } turretPosition = myCubeBlock.GetPosition(); //myLogger.debugLog("Turret Position: " + turretPosition, "Update()"); turretMissileBubble = new BoundingSphereD(turretPosition, myTurretBase.Range / 10); double distToMissile; if (currentTargetIsMissile && canLase(lastTarget) && missileIsThreat(lastTarget, out distToMissile, false)) { //myLogger.debugLog("no need to switch targets", "UpdateThread()"); return; // no need to switch targets } IMyEntity bestTarget; if (getValidTargets() && getBestTarget(out bestTarget)) { if (CurrentState != State.HAS_TARGET || lastTarget != bestTarget) { CurrentState = State.HAS_TARGET; lastTarget = bestTarget; myLogger.debugLog("new target = " + bestTarget.getBestName(), "UpdateThread()", Logger.severity.DEBUG); MainLock.UsingShared(() => myTurretBase.TrackTarget(bestTarget)); } } else // no target if (CurrentState == State.HAS_TARGET && !currentTargetIsMissile) { setNoTarget(); } } catch (Exception e) { myLogger.log("Exception: " + e, "UpdateThread()", Logger.severity.ERROR); } finally { queued = false; } }
/// <summary> /// Test required elev/azim against min/max /// Test line segment between turret and target for other entities /// </summary> private bool canLase(IMyEntity target) { Vector3D targetPos = target.GetPosition(); // Test elev/azim Vector3 relativeToBlock = RelativeVector3F.createFromWorld(targetPos - turretPosition, myCubeBlock.CubeGrid).getBlock(myCubeBlock); float azimuth, elevation; Vector3.GetAzimuthAndElevation(Vector3.Normalize(relativeToBlock), out azimuth, out elevation); //myLogger.debugLog("for target = " + target.getBestName() + ", at " + target.GetPosition() + ", elevation = " + elevation + ", azimuth = " + azimuth, "canLase()"); if (azimuth < minAzimuth || azimuth > maxAzimuth || elevation < minElevation || elevation > maxElevation) { return(false); } // if we are waiting on default targeting, ObstructingGrids will not be up-to-date if (CurrentState == State.WAIT_DTAT) { // default targeting may acquire an unowned block on a friendly grid IMyCubeGrid targetGrid = target as IMyCubeGrid; if (targetGrid == null) { IMyCubeBlock targetAsBlock = target as IMyCubeBlock; if (targetAsBlock != null) { targetGrid = targetAsBlock.CubeGrid; } } List <IMyEntity> entitiesInRange = null; BoundingSphereD range = new BoundingSphereD(turretPosition, myTurretBase.Range + 200); MainLock.UsingShared(() => { entitiesInRange = MyAPIGateway.Entities.GetEntitiesInSphere(ref range); }); foreach (IMyEntity entity in entitiesInRange) { IMyCubeGrid asGrid = entity as IMyCubeGrid; //if (asGrid != null) // myLogger.debugLog("checking entity: " + entity.getBestName(), "canLase()"); if (asGrid != null) { // default targeting may acquire an unowned block on a friendly grid if (targetGrid != null && targetGrid == asGrid) { continue; } if (!myCubeBlock.canConsiderHostile(asGrid) && IsObstructing(asGrid, targetPos)) { myLogger.debugLog("for target " + target.getBestName() + ", path from " + turretPosition + " to " + targetPos + ", obstructing entity = " + entity.getBestName(), "canLase()"); return(false); } } } } else { foreach (IMyCubeGrid grid in ObstructingGrids) { //if (grid != null) // myLogger.debugLog("checking entity: " + grid.getBestName(), "canLase()"); if (IsObstructing(grid, targetPos)) { myLogger.debugLog("for target " + target.getBestName() + ", path from " + turretPosition + " to " + targetPos + ", obstructing entity = " + grid.getBestName(), "canLase()"); return(false); } } } return(true); }
/// <summary> /// Fills validTarget_* /// </summary> private bool getValidTargets() { List <IMyEntity> entitiesInRange = null; BoundingSphereD range = new BoundingSphereD(turretPosition, myTurretBase.Range + 200); MainLock.UsingShared(() => { entitiesInRange = MyAPIGateway.Entities.GetEntitiesInSphere(ref range); }); validTarget_missile = new List <IMyEntity>(); validTarget_meteor = new List <IMyEntity>(); validTarget_character = new List <IMyEntity>(); validTarget_block = new List <IMyEntity>(); validTarget_CubeGrid = new List <IMyEntity>(); ObstructingGrids = new List <IMyEntity>(); if (!possibleTargets()) { myLogger.debugLog("no possible targets", "getValidTargets()", Logger.severity.WARNING); return(false); } //if (EnemyNear) // myLogger.debugLog("enemy near", "getValidTargets()"); //myLogger.debugLog("initial entity count is " + entitiesInRange.Count, "getValidTargets()"); foreach (IMyEntity entity in entitiesInRange) { if (entity.Transparent) // part of a ship / station being pasted { continue; } IMyCubeBlock asBlock = entity as IMyCubeBlock; if (asBlock != null) { if (asBlock.IsWorking && enemyNear() && targetGridFlagSet(asBlock.CubeGrid) && myCubeBlock.canConsiderHostile(asBlock)) { validTarget_block.Add(entity); } continue; } IMyCubeGrid asGrid = entity as IMyCubeGrid; if (asGrid != null) { if (myCubeBlock.canConsiderHostile(asGrid)) { if (targetMoving && enemyNear() && targetGridFlagSet(asGrid)) { validTarget_CubeGrid.Add(entity); } } else // not hostile { ObstructingGrids.Add(entity); } continue; } if (entity is IMyMeteor) { if (targetMeteors) { validTarget_meteor.Add(entity); } continue; } IMyPlayer asPlayer = entity as IMyPlayer; if (asPlayer != null) { if (targetCharacters) { IMyPlayer matchingPlayer = (entity as IMyCharacter).GetPlayer_Safe(); if (myCubeBlock.canConsiderHostile(matchingPlayer.PlayerID)) { validTarget_character.Add(entity); } } continue; } if (entity is IMyFloatingObject || entity is IMyVoxelMap) { continue; } // entity could be missile if (targetMissiles && enemyNear() && entity.ToString().StartsWith("MyMissile")) { validTarget_missile.Add(entity); } } //myLogger.debugLog("target counts = " + validTarget_missile.Count + ", " + validTarget_meteor.Count + ", " + validTarget_character.Count + ", " + validTarget_block.Count, "getValidTargets()"); return(validTarget_missile.Count > 0 || validTarget_meteor.Count > 0 || validTarget_character.Count > 0 || validTarget_block.Count > 0 || validTarget_CubeGrid.Count > 0); }
public Cluster(List <IMyEntity> missiles, IMyEntity launcher) { Vector3 centre = Vector3.Zero; foreach (IMyEntity miss in missiles) { centre += miss.GetPosition(); } centre /= missiles.Count; float masterDistSq = float.MaxValue; foreach (IMyEntity miss in missiles) { if (miss.Closed) { Logger.DebugLog("missile is closed: " + miss.nameWithId()); continue; } if (miss.Physics == null) { Logger.DebugLog("missile has no physics: " + miss.nameWithId()); continue; } float distSq = Vector3.DistanceSquared(centre, miss.GetPosition()); if (distSq < masterDistSq) { Master = miss; masterDistSq = distSq; } } if (Master == null) { return; } masterVelocity = Master.Physics.LinearVelocity; // master must initially have same orientation as launcher or rail will cause a rotation MatrixD masterMatrix = launcher.WorldMatrix; masterMatrix.Translation = Master.WorldMatrix.Translation; MainLock.UsingShared(() => Master.WorldMatrix = masterMatrix); Vector3 masterPos = Master.GetPosition(); MatrixD masterInv = Master.WorldMatrixNormalizedInv; float Furthest = 0f; Slaves = new List <IMyEntity>(missiles.Count - 1); SlaveOffsets = new List <Vector3>(missiles.Count - 1); foreach (IMyEntity miss in missiles) { if (miss == Master) { continue; } Slaves.Add(miss); SlaveOffsets.Add(Vector3.Transform(miss.GetPosition(), masterInv)); float distSq = Vector3.DistanceSquared(miss.GetPosition(), masterPos); Logger.DebugLog("slave: " + miss + ", offset: " + SlaveOffsets[SlaveOffsets.Count - 1], Rynchodon.Logger.severity.TRACE); if (distSq > Furthest) { Furthest = distSq; } } Furthest = (float)Math.Sqrt(Furthest); for (int i = 0; i < SlaveOffsets.Count; i++) { SlaveOffsets[i] = SlaveOffsets[i] / Furthest; } MinOffMult = Furthest * 2f; OffsetMulti = Furthest * 1e6f; // looks pretty Logger.DebugLog("created new cluster, missiles: " + missiles.Count + ", slaves: " + Slaves.Count + ", offsets: " + SlaveOffsets.Count + ", furthest: " + Furthest, Rynchodon.Logger.severity.DEBUG); }