/// <summary> /// /// SERVER ONLY FUNCTION /// /// Server will periodically determine which contacts are near a grid /// with radar and send them out in a message. This is a workaround /// for the fact that not all entities within radar range may be /// streamed to the client. /// </summary> private void DoAcquisitionSweep() { //_logger.debugLog("Running acquisition sweep", "DoAcquisitionSweep"); Vector3D pos = _grid.WorldAABB.Center; VRageMath.BoundingSphereD sphere = new VRageMath.BoundingSphereD(pos, _settings.range); List <IMyEntity> ents = MyAPIGateway.Entities.GetEntitiesInSphere(ref sphere); List <RemoteContact> contacts = new List <RemoteContact>(); foreach (IMyEntity e in ents) { if (e == _grid) { continue; } if (e is IMyCubeGrid) { Vector3D vecTo = e.WorldAABB.Center - pos; contacts.Add(new RemoteContact() { entId = e.EntityId, pos = e.WorldAABB.Center, xsec = EWMath.DetermineXSection(e as IMyCubeGrid, vecTo) }); } } // Send the contact list, even if it is blank. This is how the // client will know when distant contacts have gone out of range // or disappeared. //_logger.debugLog($"List<RemoteContact> -> Clients with {contacts.Count} entities", "DoAcquisitionSweep"); Message <BlockAddress, List <RemoteContact> > msg = new Message <BlockAddress, List <RemoteContact> >( new BlockAddress(this.GridID, this.BlockID), contacts); MyAPIGateway.Multiplayer.SendMessageToOthers( Constants.MIDAcquisitionSweep, msg.ToXML()); }
/// <summary> /// Goes through all tracks in the list and determines whether or not /// they can currently be seen. This function does not add or remove /// contacts from the list. That can only be done in ProcessAcquiredContacts. /// </summary> private void DoTrackingSweep() { //_logger.debugLog("Beginning sweep", "DoTrackingSweep"); Vector3D myPos = _grid.WorldAABB.Center; // Go through all current tracks and update their makers foreach (Track track in _allTracks.Values) { //_logger.debugLog($"For Track {track.trackId}", "DoTrackingSweep"); // If the entity is null, this track is only available on the // server so use the stored value. Otherwise get the most // up to date value if (track.ent != null) { //_logger.debugLog("Entity is not null", "DoTrackingSweep"); track.position = track.ent.WorldAABB.Center; } // Transform the coordinates into grid space so we // can compare it against our radar coverage VRageMath.Vector3D relative = VRageMath.Vector3D.Transform( track.position, _grid.WorldMatrixNormalizedInv); //Check that the sector is covered by our radars Sector sec = SectorExtensions.ClassifyVector(relative); if (IsSectorBlind(sec)) { //_logger.debugLog("Sector is blind", "DoTrackingSweep"); // If a contact is not trackable, clear its GPS marker ClearTrackMarker(track); continue; } // Vector to target Vector3D vecTo = track.position - myPos; // If the entity is available, calculate the cross-section // Otherwise we will use the stored value from the server if (track.ent != null) { track.xsec = EWMath.DetermineXSection(track.ent as IMyCubeGrid, vecTo); } double range = vecTo.Length(); double minxsec = EWMath.MinimumXSection( Constants.radarBeamWidths[(int)_assignedType], range); if (track.xsec < minxsec) { //_logger.debugLog("Cross-section not large enough", "DoTrackingSweep"); ClearTrackMarker(track); continue; } // TODO: raycast // If all of the previous checks passed, this contact should // be visible with a marker AddUpdateTrackMarker(track); } }