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); }
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); } } }
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); }
/// <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); }
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); }
/// <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; }