Exemple #1
0
        public static bool TryParse(string pretty, out double value)
        {
            pretty = pretty.Trim();

            if (string.IsNullOrWhiteSpace(pretty))
            {
                value = 0d;
                return(true);
            }

            if (double.TryParse(pretty, out value) && value.IsValid())
            {
                return(true);
            }

            Match match = Regex.Match(pretty, @"(-?\d*\.?\d*)\s*(\w*)");

            Logger.DebugLog("pretty: " + pretty + ", group count: " + match.Groups.Count);

            if (match.Groups.Count == 0)
            {
                value = default(double);
                return(false);
            }

            if (!double.TryParse(match.Groups[1].Value, out value))
            {
                return(false);
            }

            if (match.Groups.Count == 1 || string.IsNullOrWhiteSpace(match.Groups[2].Value))
            {
                return(true);
            }

            double multi = getMultiplier(SI_1000_multiples, SI_1000_subMulti, match.Groups[2].Value);

            if (multi == 0d)
            {
                return(false);
            }
            value *= multi;
            return(true);
        }
        private StringBuilder TC_Getter(IMyTerminalBlock block)
        {
            EntityVariables vars;

            if (m_active.TryGetValue(block, out vars))
            {
                Logger.DebugLog("active: " + vars.Text, context: block.nameWithId());
                return(new StringBuilder(vars.Text));
            }
            EntityValue <T> ev = TryGetEntityValue(block, false);

            if (ev != null)
            {
                Logger.DebugLog("stored value: " + ev.Value, context: block.nameWithId());
                return(new StringBuilder(ev.Value.ToString()));
            }
            //Logger.DebugLog("new", context: block.nameWithId());
            return(new StringBuilder());
        }
        /// <summary>
        /// Force vanilla terminal controls to be created for a given type of block. Always invoke this before adding controls.
        /// MyTerminalControlFactory.EnsureControlsAreCreated does not work, use this method.
        /// </summary>
        public static void EnsureTerminalControlCreated <TBlock>() where TBlock : MyTerminalBlock
        {
            if (MyTerminalControlFactory.AreControlsCreated <TBlock>())
            {
                return;
            }

            Type       blockType = typeof(TBlock);
            MethodInfo method    = blockType.GetMethod("CreateTerminalControls", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            if (method != null)
            {
                if (method.GetParameters().Length != 0)
                {
                    Logger.AlwaysLog("Method has parameters: " + method.Name + " of " + blockType.FullName, Logger.severity.ERROR);
                    return;
                }

                Logger.DebugLog("Invoking CreateTerminalControls for " + typeof(TBlock).Name, Logger.severity.DEBUG);
                // if CreateTerminalControls is changed to access fields this will throw an exception
                method.Invoke(FormatterServices.GetUninitializedObject(typeof(TBlock)), null);
                return;
            }

            method = blockType.GetMethod("CreateTerminalControls", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            if (method != null)
            {
                if (method.GetParameters().Length != 0)
                {
                    Logger.AlwaysLog("Method has parameters: " + method.Name + " of " + blockType.FullName, Logger.severity.ERROR);
                    return;
                }

                Logger.DebugLog("Invoking CreateTerminalControls for " + typeof(TBlock).Name, Logger.severity.DEBUG);
                method.Invoke(null, null);
                return;
            }

            Logger.DebugLog("No CreateTerminalControls method for " + typeof(TBlock).Name, Logger.severity.DEBUG);
        }
Exemple #4
0
 private static void RegisterClaim(IMyMotorStator stator, MotorTurret turret)
 {
     lock (claimedStator)
     {
         List <MotorTurret> users;
         if (claimedStator.TryGetValue(stator, out users))
         {
             Debug.Assert(!users.Contains(turret), turret.FaceBlock.nameWithId() + " is already in users list");
             Logger.DebugLog("registered claim: " + stator.nameWithId() + "/" + turret.FaceBlock.nameWithId());
             users.Add(turret);
             UpdateClaim(stator);
         }
         else
         {
             Logger.DebugLog("first claim: " + stator.nameWithId() + "/" + turret.FaceBlock.nameWithId());
             users = new List <MotorTurret>();
             claimedStator.Add(stator, users);
             users.Add(turret);
             SetClaim(stator, turret, true);
         }
     }
 }
Exemple #5
0
        public static MySessionComponentBase FindModSessionComponent(string modName, string modScriptsFolder, string typeName)
        {
            string assemblyName = $"{modName}_{modScriptsFolder}, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";

            CachingDictionary <Type, MySessionComponentBase> sessionComponents = (CachingDictionary <Type, MySessionComponentBase>)
                                                                                 typeof(MySession).GetField("m_sessionComponents", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(MySession.Static);

            if (sessionComponents == null)
            {
                Logger.AlwaysLog("Failed to get m_sessionComponents", Logger.severity.ERROR);
                return(null);
            }

            // Type.GetType(string typeName) with the fully qualified name doesn't seem to work, maybe it's something to do with CodeDOM
            // there can be more than one assembly with the right name
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName == assemblyName))
            {
                Type componentType = assembly.GetType(typeName);
                if (componentType == null)
                {
                    Logger.DebugLog($"Failed to get type from assembly. Assembly: {assemblyName}, Type: {typeName}", Logger.severity.TRACE);
                    continue;
                }

                MySessionComponentBase component;
                if (!sessionComponents.TryGetValue(componentType, out component))
                {
                    Logger.DebugLog($"Failed to get MySessionComponentBase. Assembly: {assemblyName}, Type: {typeName}", Logger.severity.TRACE);
                    continue;
                }

                return(component);
            }

            return(null);
        }
Exemple #6
0
        /// <summary>
        /// Estimates the proximity between a given capsule and any voxel.
        /// </summary>
        /// <param name="capsule">The capsule to test for intersection, the points must be at least one metre apart.</param>
        public static double ProximityToVoxel(ref CapsuleD capsule, out MyVoxelBase hitVoxel, out Vector3D hitPosition, bool checkPlanet, double capsuleLength = -1d)
        {
            Profiler.StartProfileBlock();
            if (capsuleLength < 0)
            {
                Vector3D.Distance(ref capsule.P0, ref capsule.P1, out capsuleLength);
            }
            double   halfLength = capsuleLength * 0.5d;
            Vector3D temp; Vector3D.Add(ref capsule.P0, ref capsule.P1, out temp);
            Vector3D middle; Vector3D.Multiply(ref temp, 0.5d, out middle);

            double          radius      = halfLength + capsule.Radius;
            BoundingSphereD worldSphere = new BoundingSphereD()
            {
                Center = middle, Radius = radius
            };

            List <MyVoxelBase> voxels = ResourcePool <List <MyVoxelBase> > .Get();

            MyGamePruningStructure.GetAllVoxelMapsInSphere(ref worldSphere, voxels);

            double closestProx = double.MaxValue;

            hitPosition = Globals.Invalid;
            foreach (MyVoxelBase voxel in voxels)
            {
                if (voxel is MyVoxelMap || voxel is MyPlanet && checkPlanet)
                {
                    if (voxel is MyPlanet)
                    {
                        LineSegmentD line;
                        ResourcePool.Get(out line);
                        line.From = capsule.P0;
                        line.To   = capsule.P1;

                        double minDistSq       = line.DistanceSquared(voxel.GetCentre());
                        double maxPlanetRadius = ((MyPlanet)voxel).MaximumRadius;

                        ResourcePool.Return(line);

                        if (minDistSq > maxPlanetRadius * maxPlanetRadius)
                        {
                            Logger.DebugLog("Skip planet from: " + line.From + ", to: " + line.To + ", planet centre: " + voxel.GetCentre() + ", min dist sq to centre: " + minDistSq + ", max planet radius: " + maxPlanetRadius);
                            continue;
                        }
                        Logger.DebugLog("Check planet from: " + line.From + ", to: " + line.To + ", planet centre: " + voxel.GetCentre() + ", min dist sq to centre: " + minDistSq + ", max planet radius: " + maxPlanetRadius);
                    }

                    double proximity = Proximity(ref capsule, voxel, ref hitPosition, capsuleLength);
                    if (proximity < closestProx)
                    {
                        Logger.TraceLog("proximity is less than closest. proximity: " + proximity + ", closest: " + closestProx);
                        closestProx = proximity;
                    }
                    if (closestProx < 1d)
                    {
                        Logger.TraceLog("closest under 1: " + closestProx);
                        hitVoxel = voxel;
                        voxels.Clear();
                        ResourcePool.Return(voxels);
                        Profiler.EndProfileBlock();
                        return(closestProx);
                    }
                }
            }

            voxels.Clear();
            ResourcePool.Return(voxels);

            hitVoxel = null;
            Profiler.EndProfileBlock();
            return(closestProx);
        }
Exemple #7
0
        public static void AppendBytes(List <byte> bytes, object data)
        {
            IConvertible convertible = data as IConvertible;

            if (convertible != null)
            {
                switch (convertible.GetTypeCode())
                {
                case TypeCode.Boolean:
                    AppendBytes(bytes, (bool)data);
                    return;

                case TypeCode.Byte:
                    AppendBytes(bytes, (byte)data);
                    return;

                case TypeCode.Int16:
                    AppendBytes(bytes, (short)data);
                    return;

                case TypeCode.UInt16:
                    AppendBytes(bytes, (ushort)data);
                    return;

                case TypeCode.Int32:
                    AppendBytes(bytes, (int)data);
                    return;

                case TypeCode.UInt32:
                    AppendBytes(bytes, (uint)data);
                    return;

                case TypeCode.Int64:
                    AppendBytes(bytes, (long)data);
                    return;

                case TypeCode.UInt64:
                    AppendBytes(bytes, (ulong)data);
                    return;

                case TypeCode.DateTime:
                    AppendBytes(bytes, ((DateTime)data).Ticks);
                    return;

                case TypeCode.Single:
                    AppendBytes(bytes, (float)data);
                    return;

                case TypeCode.Double:
                    AppendBytes(bytes, (double)data);
                    return;

                case TypeCode.String:
                    AppendBytes(bytes, (string)data);
                    return;

                default:
                    throw new Exception("No conversion for: " + convertible.GetTypeCode() + ", " + data);
                }
            }

            Type typeOfData = data.GetType();

            if (typeOfData == typeof(StringBuilder))
            {
                AppendBytes(bytes, (StringBuilder)data);
                return;
            }
            if (typeOfData == typeof(Vector3))
            {
                AppendBytes(bytes, (Vector3)data);
                return;
            }
            if (typeOfData == typeof(Vector3D))
            {
                AppendBytes(bytes, (Vector3D)data);
                return;
            }
            if (typeof(IEnumerable).IsAssignableFrom(typeOfData))
            {
                IEnumerable enumerable = (IEnumerable)data;
                int         count;
                if (typeof(ICollection).IsAssignableFrom(typeOfData))
                {
                    count = ((ICollection)data).Count;
                }
                else
                {
                    count = 0;
                    foreach (object item in enumerable)
                    {
                        ++count;
                    }
                }
                AppendBytes(bytes, count);
                foreach (object item in enumerable)
                {
                    Logger.DebugLog("Array item: " + item);
                    AppendBytes(bytes, item);
                }
                return;
            }
            throw new InvalidCastException("data is of invalid type: " + convertible?.GetTypeCode() + ", " + typeOfData + ", " + data);
        }
Exemple #8
0
        /// <summary>
        /// <para>Test line segment between startPosition and targetPosition for obstructing entities.</para>
        /// <para>Tests for obstructing voxel map, character, or grid.</para>
        ///// <param name="shortTest">When checking voxels, shortens the line by 1 m, needed to interact with an entity that may be on the surface of the voxel.</param>
        /// </summary>
        public static bool Obstructed <Tobstruct, Tignore>(LineD line, IEnumerable <Tobstruct> potentialObstructions, IEnumerable <Tignore> ignoreList, bool checkVoxel = true, bool checkPlanet = DefaultCheckPlanet)     //, bool shortTest = true)
            where Tobstruct : IMyEntity
            where Tignore : IMyEntity
        {
            Profiler.StartProfileBlock();
            // Test each entity
            foreach (IMyEntity entity in potentialObstructions)
            {
                if (entity.Closed)
                {
                    continue;
                }

                if (ignoreList != null && ignoreList.Contains((Tignore)entity))
                {
                    continue;
                }

                IMyCharacter asChar = entity as IMyCharacter;
                if (asChar != null)
                {
                    double distance;
                    if (entity.WorldAABB.Intersects(ref line, out distance))
                    {
                        Logger.DebugLog("obstructed by character: " + entity.getBestName());
                        Profiler.EndProfileBlock();
                        return(true);
                    }
                    continue;
                }

                IMyCubeGrid asGrid = entity as IMyCubeGrid;
                if (asGrid != null)
                {
                    if (!asGrid.Save)
                    {
                        continue;
                    }

                    ICollection <Vector3I> allHitCells;

                    List <Vector3I> hitCells = new List <Vector3I>();
                    asGrid.RayCastCells(line.From, line.To, hitCells);

                    allHitCells = hitCells;

                    foreach (Vector3I pos in allHitCells)
                    {
                        IMySlimBlock slim = asGrid.GetCubeBlock(pos);
                        if (slim == null)
                        {
                            continue;
                        }

                        MyCubeBlock fatblock = (MyCubeBlock)slim.FatBlock;

                        if (fatblock != null)
                        {
                            if (ignoreList != null && ignoreList.Contains((Tignore)slim.FatBlock))
                            {
                                continue;
                            }

                            Dictionary <string, MyEntitySubpart> subparts = fatblock.Subparts;
                            if (subparts != null && subparts.Count != 0)
                            {
                                Vector3     gsPosition = pos * asGrid.GridSize;
                                BoundingBox gsAABB;
                                fatblock.CombinedAABB(out gsAABB);
                                if (gsAABB.Contains(gsPosition) == ContainmentType.Disjoint)
                                {
                                    continue;
                                }
                            }
                        }

                        Logger.DebugLog("obstructed by block: " + slim.getBestName() + " on " + slim.CubeGrid.DisplayName + ", id: " + slim.CubeGrid.EntityId);
                        Profiler.EndProfileBlock();
                        return(true);
                    }
                }
            }

            if (checkVoxel)
            {
                // Voxel Test
                MyVoxelBase hitVoxel;
                Vector3D    hitPosition;
                if (RayCastVoxels(line, out hitVoxel, out hitPosition, checkPlanet))
                {
                    Logger.DebugLog("obstructed by voxel: " + hitVoxel + " at " + hitPosition);
                    Profiler.EndProfileBlock();
                    return(true);
                }
            }

            // no obstruction found
            Profiler.EndProfileBlock();
            return(false);
        }
        /// <summary>
        /// Yields the first occupied cells encountered when raycasting a grid in a given base direction.
        /// </summary>
        /// <param name="grid">The grid to get blocks from.</param>
        /// <param name="baseDirection">The direction of ray.</param>
        public static IEnumerable <Vector3I> FirstBlocks(this IMyCubeGrid grid, Vector3I baseDirection)
        {
            Logger.DebugLog("baseDirection(" + baseDirection + ") has a magnitude", Logger.severity.FATAL, condition: baseDirection.RectangularLength() != 1);

            BoundingBox localAABB = grid.LocalAABB;

            Vector3I min = grid.Min, max = grid.Max;

            // ???
            //Vector3 minF; Vector3.Divide(ref localAABB.Min, grid.GridSize, out minF);
            //Vector3 maxF; Vector3.Divide(ref localAABB.Max, grid.GridSize, out maxF);
            //Vector3I min, max;

            //Func<float, int> round = f => (int)Math.Round(f);
            //minF.ApplyOperation(round, out min);
            //maxF.ApplyOperation(round, out max);

            Vector3I perp0, perp1;

            perp0 = Base6Directions.GetIntVector(Base6Directions.GetPerpendicular(Base6Directions.GetDirection(baseDirection)));
            Vector3I.Cross(ref baseDirection, ref perp0, out perp1);

            int baseStart; Vector3I.Dot(ref baseDirection, ref min, out baseStart);
            int baseEnd; Vector3I.Dot(ref baseDirection, ref max, out baseEnd);

            if (baseStart > baseEnd)
            {
                int temp = baseStart;
                baseStart = baseEnd;
                baseEnd   = temp;
            }
            bool incrementBase = baseStart <= baseEnd;

            int perp0Min; Vector3I.Dot(ref perp0, ref min, out perp0Min);
            int perp0Max; Vector3I.Dot(ref perp0, ref max, out perp0Max);

            if (perp0Max < perp0Min)
            {
                int temp = perp0Max;
                perp0Max = perp0Min;
                perp0Min = temp;
            }

            int perp1Min; Vector3I.Dot(ref perp1, ref min, out perp1Min);
            int perp1Max; Vector3I.Dot(ref perp1, ref max, out perp1Max);

            if (perp1Max < perp1Min)
            {
                int temp = perp1Max;
                perp1Max = perp1Min;
                perp1Min = temp;
            }

            Logger.TraceLog("min: " + min + ", max: " + max, Logger.severity.DEBUG);
            Logger.TraceLog("base: " + baseDirection + ", perp0: " + perp0 + ", perp1: " + perp1, Logger.severity.DEBUG);
            Logger.TraceLog("base range: " + baseStart + ":" + baseEnd, Logger.severity.DEBUG);
            Logger.TraceLog("perp0 range: " + perp0Min + ":" + perp0Max, Logger.severity.DEBUG);
            Logger.TraceLog("perp1 range: " + perp1Min + ":" + perp1Max, Logger.severity.DEBUG);

            for (int perp0Value = perp0Min; perp0Value <= perp0Max; perp0Value++)
            {
                for (int perp1Value = perp1Min; perp1Value <= perp1Max; perp1Value++)
                {
                    int baseValue = baseStart;
                    while (true)
                    {
                        Vector3I cell = baseValue * baseDirection + perp0Value * perp0 + perp1Value * perp1;

                        if (grid.CubeExists(cell))
                        {
                            yield return(cell);

                            break;
                        }

                        if (baseValue == baseEnd)
                        {
                            break;
                        }
                        if (incrementBase)
                        {
                            baseValue++;
                        }
                        else
                        {
                            baseValue--;
                        }
                    }
                }
            }

            yield break;
        }