private static int CreateAndSendMessage_Program(long sender, string recipientGrid, string recipientBlock, string message) { int count = 0; IMyCubeBlock senderBlock; RelayStorage storage; GetStorage(sender, out senderBlock, out storage); if (storage == null) { Logger.DebugLog("No storage"); return(0); } Registrar.ForEach((ProgrammableBlock pb) => { IMyCubeBlock block = pb.m_block; IMyCubeGrid grid = block.CubeGrid; if (senderBlock.canControlBlock(block) && grid.DisplayName.looseContains(recipientGrid) && block.DisplayNameText.looseContains(recipientBlock)) { count++; storage.Receive(new Message(message, block, senderBlock)); } }); return(count); }
private static void AfterDamageHandler(object obj, MyDamageInformation damageInfo) { if (!(obj is IMySlimBlock)) { return; } // grind damage is handled by OnBlockIntegrityChanged, which is faster if (damageInfo.Type == MyDamageType.Grind) { return; } IMySlimBlock block = (IMySlimBlock)obj; long gridId = block.CubeGrid.EntityId; Registrar.ForEach((Projector proj) => { SeenHolo sh; if (!proj.m_holoEntities.TryGetValue(gridId, out sh) || !sh.Holo.Render.Visible || !sh.ColouredByIntegrity) { return; } ColourBlock(block, (IMyCubeGrid)sh.Holo); }); }
private RelayNode GetNode() { if (Globals.UpdateCount < m_nextNodeSet) { return(value_node); } m_nextNodeSet = Globals.UpdateCount + UpdateFrequency; RelayNode newNode = value_node; if (newNode == null || !IsConnected(newNode)) { newNode = null; Registrar.ForEach <RelayNode>(node => { if (node.Block != null && IsConnected(node)) { newNode = node; return(true); } return(false); }); value_node = newNode; } return(value_node); }
private static int CreateAndSendMessage_Autopilot(long sender, string recipientGrid, string recipientBlock, string message) { int count = 0; IMyCubeBlock senderBlock; RelayStorage storage; GetStorage(sender, out senderBlock, out storage); if (storage == null) { Logger.DebugLog("No storage"); return(0); } Registrar.ForEach((ShipAutopilot autopilot) => { IMyCubeBlock block = autopilot.m_block.CubeBlock; IMyCubeGrid grid = block.CubeGrid; if (senderBlock.canControlBlock(block) && grid.DisplayName.looseContains(recipientGrid) && block.DisplayNameText.looseContains(recipientBlock)) { count++; if (MyAPIGateway.Multiplayer.IsServer) { storage.Receive(new Message(message, block, senderBlock)); } } }); return(count); }
/// <summary> /// Search every possible ore detector for materials. /// </summary> /// <param name="requester">Must be able to control OreDetector and have same NetworkStorage</param> /// <param name="oreType">Voxel materials to search for</param> public static void SearchForMaterial(ShipControllerBlock requester, byte[] oreType, OreSearchComplete onComplete) { Vector3D position = requester.CubeBlock.GetPosition(); RelayStorage storage = requester.NetworkStorage; Static.m_thread.EnqueueAction(() => { List <OreDetector> oreDetectors = ResourcePool <List <OreDetector> > .Get(); Registrar.ForEach((OreDetector detector) => { if (detector.Block.IsWorking && requester.CubeBlock.canControlBlock(detector.Block) && detector.m_netClient.GetStorage() == storage) { oreDetectors.Add(detector); } }); IOrderedEnumerable <OreDetector> sorted = oreDetectors.OrderBy(detector => Vector3D.DistanceSquared(position, detector.Block.GetPosition())); foreach (OreDetector detector in sorted) { if (detector.GetOreLocations(position, oreType, onComplete)) { return; } } oreDetectors.Clear(); ResourcePool <List <OreDetector> > .Return(oreDetectors); onComplete(false, null, null, null); }); }
private void DisplyAutopilotStatus() { //Log.DebugLog("Building autopilot list", "DisplyAutopilotStatus()", Logger.severity.TRACE); RelayStorage store = m_networkClient.GetStorage(); if (store == null) { m_textPanel.WritePublicText("No network connection"); return; } List <SortableAutopilot> autopilots = ResourcePool <List <SortableAutopilot> > .Get(); Vector3D mypos = m_block.GetPosition(); Registrar.ForEach <AutopilotTerminal>(ap => { IRelayPart relayPart; if (RelayClient.TryGetRelayPart((IMyCubeBlock)ap.m_block, out relayPart) && relayPart.GetStorage() == store && m_block.canControlBlock(ap.m_block)) { autopilots.Add(new SortableAutopilot(ap, mypos)); } }); autopilots.Sort(); StringBuilder displayText = new StringBuilder(); displayText.Append(timeString); displayText.Append(DateTime.Now.ToLongTimeString()); displayText.AppendLine(); int count = 0; foreach (SortableAutopilot ap in autopilots) { displayText.Append(tab); displayText.Append(ap.Autopilot.m_block.CubeGrid.DisplayName); displayText.Append(tab); displayText.Append(PrettySI.makePretty(ap.Distance)); displayText.AppendLine("m"); ap.Autopilot.AppendingCustomInfo(displayText); displayText.AppendLine(); count++; if (count >= 5) { break; } } autopilots.Clear(); ResourcePool <List <SortableAutopilot> > .Return(autopilots); string displayString = displayText.ToString(); //Log.DebugLog("Writing to panel: " + m_textPanel.DisplayNameText + ":\n\t" + displayString, "DisplyAutopilotStatus()", Logger.severity.TRACE); m_textPanel.WritePublicText(displayText.ToString()); }
/// <summary> /// Gets the radar equipment with the highest power level from a LastSeen. /// </summary> /// <param name="gridLastSeen">LastSeen for the detected grid.</param> /// <param name="strongestEquipment">The equipment with the highest power level.</param> /// <param name="powerLevel">The power level of the equipment.</param> /// <returns>True iff a radar equipment was found.</returns> public static bool GetRadarEquipment(LastSeen gridLastSeen, out IMyCubeBlock strongestEquipment, out float powerLevel) { strongestEquipment = null; powerLevel = 0f; IMyCubeBlock strongest_in = null; float powerLevel_in = 0f; bool recentRadar = gridLastSeen.isRecent_Radar(); bool recentJammer = gridLastSeen.isRecent_Jam(); Registrar.ForEach((RadarEquipment re) => { if (re.CubeBlock.CubeGrid == gridLastSeen.Entity) { if (!re.IsWorking) { return; } float reStr = 0f; if (recentRadar && re.myDefinition.Radar) // PowerLevel_Radar can be > 0 even if it is not a radar { reStr = re.PowerLevel_Radar; } if (recentJammer && re.PowerLevel_Jammer > reStr) { reStr = re.PowerLevel_Jammer; } if (reStr > powerLevel_in) { powerLevel_in = reStr; strongest_in = re.CubeBlock; } } }); strongestEquipment = strongest_in; powerLevel = powerLevel_in; return(strongestEquipment != null); }
/// <summary> /// Updates direct connections between this node and other nodes. /// When debug is set, checks connection to primary storage node. /// </summary> public void Update100() { s_sendPositionTo.Clear(); bool checkPrimary = false; Registrar.ForEach((RelayNode node) => { if (node == this) { return; } CommunicationType connToNode = TestConnection(node); if (connToNode == CommunicationType.TwoWay) { if (m_directConnect.Add(node)) { Log.TraceLog("Now connected to " + node.DebugName, Logger.severity.DEBUG); if (this.Storage == null) { if (node.Storage != null) { Log.TraceLog("Using storage from other node: " + node.DebugName + ", primary: " + node.Storage.PrimaryNode.DebugName, Logger.severity.DEBUG); this.Storage = node.Storage; } } else if (node.Storage != null && this.Storage != node.Storage) { // should prefer blocks since they are less likely to be removed from world while offline if (this.Block != null && node.Block == null) { Log.TraceLog("Nodes have different storages, copying to this node's storage because this node is a block", Logger.severity.DEBUG); node.Storage.CopyTo(this.Storage); node.Storage = this.Storage; } else if (this.Block == null && node.Block != null) { Log.TraceLog("Nodes have different storages, copying to other node's storage beacause other node is a block", Logger.severity.DEBUG); this.Storage.CopyTo(node.Storage); this.Storage = node.Storage; } else if (this.Storage.Size < node.Storage.Size) { Log.TraceLog("Nodes have different storages, copying to other node's storage", Logger.severity.DEBUG); this.Storage.CopyTo(node.Storage); this.Storage = node.Storage; } else { Log.TraceLog("Nodes have different storages, copying to this node's storage", Logger.severity.DEBUG); node.Storage.CopyTo(this.Storage); node.Storage = this.Storage; } } } } else { if (m_directConnect.Remove(node)) { Log.TraceLog("No longer connected to " + node.DebugName, Logger.severity.DEBUG); checkPrimary = true; } } if (Storage != null) { if (connToNode == CommunicationType.OneWay) { if (m_oneWayConnect.Add(node)) { Log.TraceLog("New one-way connection to " + node.DebugName, Logger.severity.DEBUG); Storage.AddPushTo(node); } } else { if (m_oneWayConnect.Remove(node)) { Log.TraceLog("Lost one-way connection to " + node.DebugName, Logger.severity.DEBUG); Storage.RemovePushTo(node); } } } }); if (Storage == null) { Log.DebugLog("No storage, creating a new one", Logger.severity.INFO); Storage = new RelayStorage(this); } else if (checkPrimary && !IsConnectedTo(Storage.PrimaryNode)) { Log.DebugLog("Lost connection to primary, cloning storage", Logger.severity.INFO); Storage = Storage.Clone(this); } // connections don't update immediately, so don't worry about a single message (per block) Log.TraceLog("Not connected to primary node", Logger.severity.INFO, condition: !IsConnectedTo(Storage.PrimaryNode)); IMyEntity topEntity = m_entity.GetTopMostParent(); Log.TraceLog("Sending self to " + s_sendPositionTo.Count + " neutral/hostile storages", Logger.severity.TRACE); RelayStorage.Receive(s_sendPositionTo, new LastSeen(topEntity, LastSeen.DetectedBy.Broadcasting)); if (Storage.VeryRecentRadarInfo(topEntity.EntityId)) { return; } if (Block == null) { Storage.Receive(new LastSeen(topEntity, LastSeen.DetectedBy.Broadcasting, new LastSeen.RadarInfo(topEntity))); } else { foreach (IMyCubeGrid grid in AttachedGrid.AttachedGrids(Block.CubeGrid, AttachedGrid.AttachmentKind.Terminal, true)) { Storage.Receive(new LastSeen(grid, LastSeen.DetectedBy.Broadcasting, new LastSeen.RadarInfo(grid))); } } }
private void PassiveDetection(bool radar) { float detectionThreshold; if (radar) { if (!CanPassiveDetectRadar) { return; } detectionThreshold = myDefinition.PassiveDetect_Radar; } else { if (!CanPassiveDetectJammer) { return; } detectionThreshold = myDefinition.PassiveDetect_Jamming; } Registrar.ForEach((RadarEquipment otherDevice) => { if (!otherDevice.IsWorking) { return; } IMyEntity otherEntity = otherDevice.Entity.Hierarchy.GetTopMostParent().Entity; if (m_node.Storage.VeryRecentRadarInfo(otherEntity.EntityId)) { return; } float otherPowerLevel = radar ? otherDevice.PowerLevel_Radar : otherDevice.PowerLevel_Jammer; if (otherPowerLevel <= 0) { return; } otherPowerLevel *= myDefinition.SignalEnhance; if (SignalCannotReach(otherDevice.Entity, otherPowerLevel)) { return; } float distance = Vector3.Distance(Entity.GetCentre(), otherDevice.Entity.GetCentre()); float signalStrength = otherPowerLevel - distance - detectionThreshold; signalStrength += decoySignal * WorkingDecoys(otherDevice); if (signalStrength > 0) { Log.DebugLog("radar signal seen: " + otherDevice.Entity.getBestName(), Logger.severity.TRACE); DetectedInfo detFo; if (detectedObjects_hash == null || !detectedObjects_hash.TryGetValue(otherEntity, out detFo)) { detFo = new DetectedInfo(otherEntity, RelationsBlock.getRelationsTo(otherDevice.RelationsBlock)); detectedObjects_list.Add(detFo); if (detectedObjects_hash != null) { detectedObjects_hash.Add(otherEntity, detFo); } } if (radar) { detFo.RadarSignal = signalStrength; } else { detFo.JammerSignal = signalStrength; } } }); }
private void JamRadar() { ClearJamming(); MathHelper.Clamp(PowerRatio_Jammer, 0f, 1f); float effectivePowerLevel = PowerLevel_Current * myDefinition.SignalEnhance; if (effectivePowerLevel <= 0) { Log.DebugLog("no power for jamming"); return; } //int allowedTargets = MathHelper.Floor(myDefinition.MaxTargets_Jamming * PowerRatio_Jammer); //Log.DebugLog("jamming power level: " + effectivePowerLevel + ", allowedTargets: " + allowedTargets, "JamRadar()"); // collect targets Registrar.ForEach((RadarEquipment otherDevice) => { if (!otherDevice.IsRadar || !otherDevice.IsWorking) { return; } if (SignalCannotReach(otherDevice.Entity, effectivePowerLevel)) { return; } bool notHostile = !RelationsBlock.canConsiderHostile(otherDevice.RelationsBlock); if (notHostile && myDefinition.JamIncidental == 0f) { Log.DebugLog("cannot jam a friendly: " + otherDevice.Entity.getBestName(), Logger.severity.TRACE); return; } float distance = Vector3.Distance(Entity.GetCentre(), otherDevice.Entity.GetCentre()); float signalStrength = effectivePowerLevel - distance; if (signalStrength > 0) { if (notHostile) { Log.DebugLog("adding friendly: " + otherDevice.Entity.getBestName(), Logger.severity.TRACE); jamming_friendly.Add(signalStrength, otherDevice); } else { Log.DebugLog("adding enemy: " + otherDevice.Entity.getBestName(), Logger.severity.TRACE); jamming_enemy.Add(signalStrength, otherDevice); } } }); // apply jamming if (jamming_enemy.Count == 0) { Log.DebugLog("no targets to jam", Logger.severity.TRACE); jamming_friendly.Clear(); PowerRatio_Jammer = 0f; return; } // Up to MaximumTargets, radars will be deliberately jammed. Others will be incidentally jammed deliberateJamming = 0; foreach (var pair in jamming_enemy) { if (deliberateJamming < myDefinition.MaxTargets_Jamming) { Log.DebugLog("jamming enemy: " + pair.Value.Entity.getBestName() + ", strength: " + pair.Key, Logger.severity.TRACE); pair.Value.beingJammedBy.Add(this, pair.Key); deliberateJamming++; } else { Log.DebugLog("incidentally jamming enemy: " + pair.Value.Entity.getBestName() + ", strength: " + pair.Key * myDefinition.JamIncidental, Logger.severity.TRACE); pair.Value.beingJammedBy.Add(this, pair.Key * myDefinition.JamIncidental); } } PowerRatio_Jammer = (float)deliberateJamming / (float)myDefinition.MaxTargets_Jamming; Log.DebugLog("PowerRatio_Jammer: " + PowerRatio_Jammer, Logger.severity.TRACE); foreach (var pair in jamming_friendly) { Log.DebugLog("incidentally jamming friendly: " + pair.Value.Entity.getBestName() + ", strength: " + pair.Key * myDefinition.JamIncidental, Logger.severity.TRACE); pair.Value.beingJammedBy.Add(this, pair.Key * myDefinition.JamIncidental); } }
[OnWorldSave(Order = int.MaxValue)] // has to be last, obviously private static void SaveData() { if (!MyAPIGateway.Multiplayer.IsServer) { return; } try { // fetching data needs to happen on game thread as not every script has locks Builder_ArmsData data = new Builder_ArmsData(); data.SaveTime = Globals.ElapsedTimeTicks; data.ArmsVersion = Settings.ServerSettings.CurrentVersion; // network data Dictionary <long, RelayStorage.Builder_NetworkStorage> storages = new Dictionary <long, RelayStorage.Builder_NetworkStorage>(); Registrar.ForEach <RelayNode>(node => { if (node.Block != null && node.Storage != null && !storages.ContainsKey(node.Storage.PrimaryNode.EntityId)) { RelayStorage.Builder_NetworkStorage bns = node.Storage.GetBuilder(); if (bns != null) { storages.Add(bns.PrimaryNode, bns); } } }); data.AntennaStorage = storages.Values.ToArray(); // disruption List <Disruption.Builder_Disruption> systemDisrupt = new List <Disruption.Builder_Disruption>(); foreach (Disruption disrupt in Disruption.AllDisruptions) { systemDisrupt.Add(disrupt.GetBuilder()); } data.SystemDisruption = systemDisrupt.ToArray(); // autopilot List <ShipAutopilot.Builder_Autopilot> buildAuto = new List <ShipAutopilot.Builder_Autopilot>(); Registrar.ForEach <ShipAutopilot>(autopilot => { ShipAutopilot.Builder_Autopilot builder = autopilot.GetBuilder(); if (builder != null) { buildAuto.Add(builder); } }); data.Autopilot = buildAuto.ToArray(); // Sync data.Sync = ASync.GetBuilder(); MyAPIGateway.Utilities.SetVariable(SaveXml, MyAPIGateway.Utilities.SerializeToXML(data)); if (Instance.m_fileMaster != null) { string identifier = Instance.LegacyIdentifier(false); if (identifier != null) { if (Instance.m_fileMaster.Delete(identifier)) { Rynchodon.Logger.DebugLog("file deleted: " + identifier); } } } } catch (Exception ex) { Rynchodon.Logger.AlwaysLog("Exception: " + ex, Rynchodon.Logger.severity.ERROR); Rynchodon.Logger.Notify("ARMS: failed to save data", 60000, Rynchodon.Logger.severity.ERROR); } }