public override void ProcessServer() { ScanSettingsEntity scanSettings = ScanDataManager.GetPlayerScanData(SenderSteamId); TrackDetailEntity detail = null; if (!string.IsNullOrEmpty(ShipName)) { int index; if (ShipName.Substring(0, 1) == "#" && int.TryParse(ShipName.Substring(1), out index) && index > 0 && index <= scanSettings.ScanHostList.Count) { detail = scanSettings.ScanHostList[index - 1]; } if (detail == null) { MyAPIGateway.Utilities.SendMessage(SenderSteamId, "Track failed", "Object '{0}' not found.", ShipName); return; } } // send an empty TrackEntity if no shipname is provided. This Action should clear any current tracking. ConnectionHelper.SendMessageToPlayer(SenderSteamId, new PushSetTrack { TrackEntity = detail }); }
public override void ProcessServer() { ScanSettingsEntity scanSettings = ScanDataManager.GetPlayerScanData(SenderSteamId); var player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); switch (DisplayType) { case ScanType.GpsCoordinates: if (scanSettings.ScanListGpsEntities == null || player == null) { return; } foreach (var trackEntity in scanSettings.ScanListGpsEntities) { MyAPIGateway.Session.GPS.RemoveGps(player.IdentityId, trackEntity.GpsHash); } scanSettings.ScanListGpsEntities.Clear(); break; case ScanType.ChatConsole: case ScanType.MissionScreen: scanSettings.ScanHostList.Clear(); break; } }
public override void Help(ulong steamId, bool brief) { // needs to be called server side to fetch settings. We aren't storing any of this client side. ScanSettingsEntity scanSettings = ScanDataManager.GetPlayerScanData(steamId); var ignoreList = new List <string>(); if (scanSettings.IgnoreJunk) { ignoreList.Add(MassCategory.Junk.ToString()); } if (scanSettings.IgnoreTiny) { ignoreList.Add(MassCategory.Tiny.ToString()); } if (scanSettings.IgnoreSmall) { ignoreList.Add(MassCategory.Small.ToString()); } if (scanSettings.IgnoreLarge) { ignoreList.Add(MassCategory.Large.ToString()); } if (scanSettings.IgnoreHuge) { ignoreList.Add(MassCategory.Huge.ToString()); } if (scanSettings.IgnoreEnormous) { ignoreList.Add(MassCategory.Enormous.ToString()); } if (scanSettings.IgnoreRidiculous) { ignoreList.Add(MassCategory.Ridiculous.ToString()); } var description = $@"/ignore <type> <state> Function: Ignores the specified mass type by allowing you switch it on or off. <type> must be one of ""Junk, Tiny, Small, Large, Huge, Enormous, Ridiculous"". <state> must be ""On"" or ""Off"". ie. /ignore Junk On /ignore Enormous Off Abbreviations can be used. /ignore ju 1 /ignore en 0 Currently Ignoring: {string.Join(", ", ignoreList)} "; MyAPIGateway.Utilities.SendMissionScreen(steamId, "/Ignore Help", null, " ", description, null, "OK"); }
public static ScanSettingsEntity GetPlayerScanData(ulong steamId) { ScanServerEntity scanServerData = ((MySampleModLogic)MainChatCommandLogic.Instance).ServerData; ScanSettingsEntity playerScanData = scanServerData.Clients.FirstOrDefault(e => e.SteamId == steamId); if (playerScanData == null) { playerScanData = new ScanSettingsEntity { SteamId = steamId }; scanServerData.Clients.Add(playerScanData); } return(playerScanData); }
private void ScanShips(ulong steamId, double minRange, ScanType displayType, ScanSettingsEntity settings) { IMyPlayer player = MyAPIGateway.Players.FindPlayerBySteamId(SenderSteamId); IMyEntity controlledEntity = MyAPIGateway.Entities.GetEntityById(ControlledEntityId); if (player == null) { MainChatCommandLogic.Instance.ServerLogger.WriteVerbose($"Scan failed. Player information passed was invalid, or old. SenderSteamId={SenderSteamId}"); MyAPIGateway.Utilities.SendMessage(steamId, "Scan failed", "Mod/Game failure."); return; } if (controlledEntity == null) { MainChatCommandLogic.Instance.ServerLogger.WriteVerbose($"Scan failed. information passed was invalid, or old. ControlledEntityId={ControlledEntityId}"); MyAPIGateway.Utilities.SendMessage(steamId, "Scan failed", "Mod/Game failure."); return; } // TODO: background progessing. GetEntitiesInSphere is a very intensive call. //MyAPIGateway.Parallel. var cockpit = controlledEntity as IMyCubeBlock; if (controlledEntity.Parent == null || cockpit == null) { MyAPIGateway.Utilities.SendMessage(steamId, "Scan failed", "Player is not in ship."); return; } var definition = MyDefinitionManager.Static.GetCubeBlockDefinition(cockpit.BlockDefinition); var cockpitDefinition = definition as MyCockpitDefinition; var remoteDefinition = definition as MyRemoteControlDefinition; if ((cockpitDefinition == null || !cockpitDefinition.EnableShipControl) && (remoteDefinition == null || !remoteDefinition.EnableShipControl)) { MyAPIGateway.Utilities.SendMessage(steamId, "Scan failed", "Player must be in cockpit/remote and cannot be passenger."); return; } var cubeGrid = (IMyCubeGrid)controlledEntity.GetTopMostParent(); var blocks = new List <IMySlimBlock>(); cubeGrid.GetBlocks(blocks, b => b?.FatBlock != null && !b.FatBlock.BlockDefinition.TypeId.IsNull && b.FatBlock.BlockDefinition.TypeId == typeof(MyObjectBuilder_RadioAntenna) && b.FatBlock.IsWorking); if (blocks.Count == 0) { MyAPIGateway.Utilities.SendMessage(steamId, "Scan failed", "No working antenna found."); return; } float effectiveRadius = 0f; Vector3D scanPoint = Vector3D.Zero; // TODO: maybe extend this to use all available fixed antenna on the ship/station, as the antenna may offer a better spread on a large ship/station. // Not planning to use all in-range antenna however. foreach (var block in blocks) { var relation = block.FatBlock.GetUserRelationToOwner(player.IdentityId); if (relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare) { var z = block.FatBlock.GetObjectBuilderCubeBlock(); var y = (MyObjectBuilder_RadioAntenna)z; if (y.EnableBroadcasting) { var radi = y.BroadcastRadius; if (effectiveRadius < radi) { effectiveRadius = radi; scanPoint = block.FatBlock.WorldAABB.Center; } } } } if (effectiveRadius == 0f) { MyAPIGateway.Utilities.SendMessage(steamId, "Scan failed", "No working/owned antenna found."); return; } MyAPIGateway.Utilities.SendMessage(steamId, "Scanning", "..."); List <ShipGridExtension> shipGrids = new List <ShipGridExtension>(); var playerPosition = controlledEntity.GetPosition(); int fullCount = 0; MyAPIGateway.Parallel.StartBackground( delegate { // Find all grids within range of the Antenna broadcast sphere. var sphere = new BoundingSphereD(scanPoint, effectiveRadius); var floatingList = MyAPIGateway.Entities.GetTopMostEntitiesInSphere(ref sphere).Where(e => (e is IMyCubeGrid)).Cast <IMyCubeGrid>().ToArray(); //var allEntites = new HashSet<IMyEntity>(); // Remove grids without physics, these should be projected grids. //MyAPIGateway.Entities.GetEntities(allEntites, e => (e is IMyCubeGrid) && Vector3D.Distance(scanPoint, e.WorldAABB.Center) <= effetiveRadius && e.Physics != null); //var floatingList = allEntites.Cast<IMyCubeGrid>().ToArray(); foreach (var cubeGridPart in floatingList) { //MyAPIGateway.Utilities.SendMessage(steamId, "name", string.Format("'{0}' {1}.", cubeGridPart.DisplayName, cubeGridPart.GetTopMostParent().DisplayName)); // Collate the grids, into gourps where they are joined by Rotors, Pistons, or Wheels. if (!shipGrids.Any(s => s.GridGroups.Any(g => g.EntityId == cubeGridPart.EntityId))) { var gridGroups = cubeGridPart.GetAttachedGrids(); //MyAPIGateway.Utilities.SendMessage(steamId, "groups", string.Format("{0}.", gridGroups.Count)); // Check if the is not powered or Owned in any way. if (!gridGroups.IsPowered() && !gridGroups.IsOwned()) { var pos = gridGroups.Center(); var distance = Math.Sqrt((playerPosition - pos).LengthSquared()); if (distance >= minRange) { var ship = new ShipGridExtension { GridGroups = gridGroups, Distance = distance, Position = pos }; shipGrids.Add(ship); } } } } fullCount = shipGrids.Count; // Filter the ignore list. shipGrids = shipGrids.Where(e => !(settings.IgnoreJunk && e.MassCategory == MassCategory.Junk)).ToList(); shipGrids = shipGrids.Where(e => !(settings.IgnoreTiny && e.MassCategory == MassCategory.Tiny)).ToList(); shipGrids = shipGrids.Where(e => !(settings.IgnoreSmall && e.MassCategory == MassCategory.Small)).ToList(); shipGrids = shipGrids.Where(e => !(settings.IgnoreLarge && e.MassCategory == MassCategory.Large)).ToList(); shipGrids = shipGrids.Where(e => !(settings.IgnoreHuge && e.MassCategory == MassCategory.Huge)).ToList(); shipGrids = shipGrids.Where(e => !(settings.IgnoreEnormous && e.MassCategory == MassCategory.Enormous)).ToList(); shipGrids = shipGrids.Where(e => !(settings.IgnoreRidiculous && e.MassCategory == MassCategory.Ridiculous)).ToList(); settings.ScanHostList.Clear(); }, delegate { switch (displayType) { case ScanType.MissionScreen: { var prefix = $"Scan range: {effectiveRadius}m : {shipGrids.Count} derelict masses detected."; if (fullCount != shipGrids.Count) { prefix += $"\r\n{fullCount - shipGrids.Count} masses ignored."; } var description = new StringBuilder(); var index = 1; foreach (var ship in shipGrids.OrderBy(s => s.Distance)) { var heading = Support.GetRotationAngle(PlayerPositionMatrix, ship.Position - playerPosition); description.AppendFormat("#{0} : Rn:{3:N}m, El:{4:N}°, Az:{5:N}° : {1} {2}\r\n", index++, ship.SpeedCategory, ship.MassCategory, ship.Distance, heading.Y, heading.X); settings.ScanHostList.Add(new TrackDetailEntity(ship.Position, $"{ship.SpeedCategory} {ship.MassCategory} Derelict" /*, ship.GridGroups.Select(e => e.EntityId) */)); } MyAPIGateway.Utilities.SendMissionScreen(steamId, "Scan Results", prefix, " ", description.ToString(), null, "OK"); } break; case ScanType.ChatConsole: { var index = shipGrids.Count; foreach (var ship in shipGrids.OrderByDescending(s => s.Distance)) { var heading = Support.GetRotationAngle(PlayerPositionMatrix, ship.Position - playerPosition); MyAPIGateway.Utilities.SendMessage(steamId, $"#{index--}", string.Format("Rn:{2:N}m, El:{3:N}°, Az:{4:N}° : {0} {1}", ship.SpeedCategory, ship.MassCategory, ship.Distance, heading.Y, heading.X)); settings.ScanHostList.Add(new TrackDetailEntity(ship.Position, $"{ship.SpeedCategory} {ship.MassCategory} Derelict" /*, ship.GridGroups.Select(e => e.EntityId) */)); } MyAPIGateway.Utilities.SendMessage(steamId, "Scan range", "{0}m : {1} derelict masses detected.", effectiveRadius, shipGrids.Count); } break; case ScanType.GpsCoordinates: { if (settings.ScanListGpsEntities == null) { settings.ScanListGpsEntities = new List <TrackGpsEntity>(); } var updateCount = 0; foreach (var ship in shipGrids) { var entityIds = ship.GridGroups.Select(e => e.EntityId).ToList(); foreach (var entityId in entityIds) { var trackEntity = settings.ScanListGpsEntities.FirstOrDefault(t => t.Entities.Any(e => e == entityId)); if (trackEntity != null && trackEntity.GpsHash != 0) { settings.ScanListGpsEntities.Remove(trackEntity); //MyAPIGateway.Session.GPS.RemoveLocalGps(trackEntity.GpsHash); MyAPIGateway.Session.GPS.RemoveGps(player.IdentityId, trackEntity.GpsHash); updateCount++; } } } foreach (var ship in shipGrids) { var name = $"Derelict {ship.SpeedCategory} {ship.MassCategory}"; var description = "Derelict craft"; var gps = MyAPIGateway.Session.GPS.Create(name, description, ship.Position, true, false); //MyAPIGateway.Session.GPS.AddLocalGps(gps); MyAPIGateway.Session.GPS.AddGps(player.IdentityId, gps); settings.ScanListGpsEntities.Add(new TrackGpsEntity { GpsHash = gps.Hash, Entities = ship.GridGroups.Select(e => e.EntityId).ToList() }); } MyAPIGateway.Utilities.SendMessage(steamId, "Scan range", "{0}m : {1}/{2} new derelict masses detected.", effectiveRadius, shipGrids.Count - updateCount, shipGrids.Count); } break; } }); }
public override void ProcessServer() { ScanSettingsEntity scanSettings = ScanDataManager.GetPlayerScanData(SenderSteamId); ScanShips(SenderSteamId, (double)MinRange, DisplayType, scanSettings); }
public override bool Invoke(ulong steamId, long playerId, string messageText) { var commands = messageText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (commands.Length < 3) { Help(steamId, false); return(true); } MassCategory[] categories = (MassCategory[])Enum.GetValues(typeof(MassCategory)); string massclass = null; foreach (var category in categories) { if (category.ToString().Equals(commands[1], StringComparison.InvariantCultureIgnoreCase)) { massclass = category.ToString(); break; } } if (massclass == null) { var matches = categories.Where(s => s.ToString().StartsWith(commands[1], StringComparison.InvariantCultureIgnoreCase)).Distinct().ToArray(); if (matches.Length == 1) { massclass = matches.FirstOrDefault().ToString(); } } if (massclass == null) { Help(steamId, false); return(true); } bool setIgnore; if (commands[2].TryWordParseBool(out setIgnore)) { ScanSettingsEntity scanSettings = ScanDataManager.GetPlayerScanData(steamId); if (massclass == MassCategory.Junk.ToString()) { scanSettings.IgnoreJunk = setIgnore; } if (massclass == MassCategory.Tiny.ToString()) { scanSettings.IgnoreTiny = setIgnore; } if (massclass == MassCategory.Small.ToString()) { scanSettings.IgnoreSmall = setIgnore; } if (massclass == MassCategory.Large.ToString()) { scanSettings.IgnoreLarge = setIgnore; } if (massclass == MassCategory.Huge.ToString()) { scanSettings.IgnoreHuge = setIgnore; } if (massclass == MassCategory.Enormous.ToString()) { scanSettings.IgnoreEnormous = setIgnore; } if (massclass == MassCategory.Ridiculous.ToString()) { scanSettings.IgnoreRidiculous = setIgnore; } MyAPIGateway.Utilities.SendMessage(steamId, $"Ignore {massclass}", setIgnore ? "On" : "Off"); return(true); } Help(steamId, false); return(true); }