Example #1
0
        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);
        }
Example #2
0
        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);
            });
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        /// <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);
            });
        }
Example #6
0
        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());
        }
Example #7
0
        /// <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);
        }
Example #8
0
        /// <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)));
                }
            }
        }
Example #9
0
        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;
                    }
                }
            });
        }
Example #10
0
        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);
            }
        }
Example #11
0
        [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);
            }
        }