/// <summary> /// Adds a missile to this missile's cluster. /// </summary> /// <returns>true iff at/past maximum cluster size</returns> public bool AddToCluster(IMyEntity missile) { if (myCluster.Slaves.Count == myCluster.Max) { myLogger.alwaysLog("extra cluster part fired", "AddToCluster()", Logger.severity.WARNING); missile.Delete(); return true; } myCluster.Slaves.Enqueue(missile); AddMissileOwner(missile, CubeBlock.OwnerId); myLogger.debugLog("added to cluster, count is " + myCluster.Slaves.Count, "AddToCluster()"); if (myCluster.Slaves.Count == myCluster.Max) { myLogger.debugLog("reached maximum cluster size", "AddToCluster()"); return true; } return false; }
private bool MissileBelongsTo(IMyEntity missile) { if (!(CubeBlock as Ingame.IMyUserControllableGun).IsShooting) { myLogger.debugLog("Not mine, not shooting", "MissileBelongsTo()"); return false; } Vector3D local = Vector3D.Transform(missile.GetPosition(), CubeBlock.WorldMatrixNormalizedInv); if (MissileSpawnBox.Contains(local) != ContainmentType.Contains) { myLogger.debugLog("Not in my box: " + missile + ", position: " + local, "MissileBelongsTo()"); return false; } if (Vector3D.RectangularDistance(CubeBlock.WorldMatrix.Forward, missile.WorldMatrix.Forward) > 0.01) { myLogger.debugLog("Facing the wrong way: " + missile + ", RectangularDistance: " + Vector3D.RectangularDistance(CubeBlock.WorldMatrix.Forward, missile.WorldMatrix.Forward), "MissileBelongsTo()"); return false; } if (loadedAmmo == null) { myLogger.debugLog("Mine but no loaded ammo!", "MissileBelongsTo()", Logger.severity.INFO); return true; } if (loadedAmmo.Description == null || loadedAmmo.Description.GuidanceSeconds < 1f) { myLogger.debugLog("Mine but not a guided missile!", "MissileBelongsTo()", Logger.severity.INFO); return true; } myLogger.debugLog("Opts: " + myFixed.Options, "MissileBelongsTo()"); try { if (clusterMain != null) { if (loadedAmmo.IsCluster) { if (clusterMain.AddToCluster(missile)) { myLogger.debugLog("reached max cluster, on cooldown", "MissileBelongsTo()", Logger.severity.DEBUG); StartCooldown(); } } else { myLogger.alwaysLog("deleting extraneous missile: " + missile, "MissileBelongsTo()", Logger.severity.WARNING); missile.Delete(); } return true; } LastSeen initialTarget = null; if (findAntenna()) { if (myFixed.Options.TargetEntityId.HasValue) myAntenna.tryGetLastSeen(myFixed.Options.TargetEntityId.Value, out initialTarget); else { myLogger.debugLog("Searching for target", "MissileBelongsTo()", Logger.severity.DEBUG); float closestDistanceSquared = float.MaxValue; myAntenna.ForEachLastSeen(seen => { if (!seen.isRecent()) return false; IMyCubeGrid grid = seen.Entity as IMyCubeGrid; if (grid != null && CubeBlock.canConsiderHostile(grid) && myFixed.Options.CanTargetType(grid)) { float distSquared = Vector3.DistanceSquared(CubeBlock.GetPosition(), grid.GetCentre()); if (distSquared < closestDistanceSquared) { closestDistanceSquared = distSquared; initialTarget = seen; } } return false; }); } } myLogger.debugLog("creating new guided missile", "MissileBelongsTo()"); GuidedMissile gm = new GuidedMissile(missile as MyAmmoBase, CubeBlock, myFixed.Options.Clone(), loadedAmmo, initialTarget); if (loadedAmmo.IsCluster) { myLogger.debugLog("missile is a cluster missile", "MissileBelongsTo()"); clusterMain = gm; missile.OnClose += ClusterMain_OnClose; var builder = CubeBlock.GetObjectBuilder_Safe() as MyObjectBuilder_UserControllableGun ; restoreShootingToggle = builder.IsShootingFromTerminal; FuncBlock.ApplyAction("Shoot_On"); } } catch (Exception ex) { myLogger.alwaysLog("failed to create GuidedMissile", "MissileBelongsTo()", Logger.severity.ERROR); myLogger.alwaysLog("Exception: " + ex, "MissileBelongsTo()", Logger.severity.ERROR); } return true; }