Example #1
0
 private static void ProcessOxygenGenerator(MyObjectBuilder_CubeBlock block, Options options, MyCubeSize size)
 {         // Has it's own inventory, supporting function to add inventory doesn't work on this block
     if (!options.Restock)
     {
         return;
     }
     try
     {
         MyObjectBuilder_Ore ice = new MyObjectBuilder_Ore {
             SubtypeName = "Ice"
         };
         MyPhysicalItemDefinition iceDefinition = MyDefinitionManager.Static.GetPhysicalItemDefinition(ice.GetId());
         ((MyObjectBuilder_OxygenGenerator)block).Inventory.Clear();
         ((MyObjectBuilder_OxygenGenerator)block).Inventory.Items.Add(
             new MyObjectBuilder_InventoryItem
         {
             Amount          = (int)((GetMaxVolume(block, size) / iceDefinition.Volume) * 0.90),                  // I want to leave some room for bottles
             PhysicalContent = ice
         });
         Core.GeneralLog.WriteToLog("MyObjectBuilder_OxygenGenerator", $"Amount:\t{(int)((GetMaxVolume(block, size) / iceDefinition.Volume) * 0.9)}");
     }
     catch (Exception e)
     {
         Core.GeneralLog.WriteToLog("MyObjectBuilder_OxygenGenerator", $"Exception! {e}");
     }
 }
Example #2
0
        private void UnmountInternal(float unmountAmount, MyConstructionStockpile outputStockpile = null, bool damageItems = false, bool useDefaultDeconstructEfficiency = false)
        {
            float topComponentIntegrity = this.GetTopComponentIntegrity();
            int   topGroupIndex         = this.m_topGroupIndex;
            int   topComponentIndex     = this.m_topComponentIndex;
            MyObjectBuilder_PhysicalObject physicalObject = null;
            MyObjectBuilder_Ore            scrapBuilder   = MyFloatingObject.ScrapBuilder;

            while ((unmountAmount * this.GetDeconstructionEfficiency(topGroupIndex, damageItems | useDefaultDeconstructEfficiency)) >= topComponentIntegrity)
            {
                this.Integrity -= topComponentIntegrity;
                unmountAmount  -= topComponentIntegrity;
                if ((outputStockpile != null) && MySession.Static.SurvivalMode)
                {
                    bool flag = damageItems && MyFakes.ENABLE_DAMAGED_COMPONENTS;
                    if (!damageItems || (flag && (MyRandom.Instance.NextFloat() <= this.m_blockDefinition.Components[topGroupIndex].Definition.DropProbability)))
                    {
                        physicalObject = (MyObjectBuilder_PhysicalObject)MyObjectBuilderSerializer.CreateNewObject((SerializableDefinitionId)this.m_blockDefinition.Components[topGroupIndex].DeconstructItem.Id);
                        if (flag)
                        {
                            physicalObject.Flags |= MyItemFlags.Damaged;
                        }
                        if ((this.Integrity > 0f) || this.m_yieldLastComponent)
                        {
                            outputStockpile.AddItems(1, physicalObject);
                        }
                    }
                    MyComponentDefinition definition = this.m_blockDefinition.Components[topGroupIndex].Definition;
                    if (((MyFakes.ENABLE_SCRAP & damageItems) && (MyRandom.Instance.NextFloat() < definition.DropProbability)) && ((this.Integrity > 0f) || this.m_yieldLastComponent))
                    {
                        outputStockpile.AddItems((int)(0.8f * definition.Mass), scrapBuilder);
                    }
                }
                topComponentIndex--;
                if (topComponentIndex < 0)
                {
                    topGroupIndex--;
                    if (topGroupIndex < 0)
                    {
                        this.SetTopIndex(0, 0);
                        this.Integrity = 0f;
                        return;
                    }
                    topComponentIndex = this.m_blockDefinition.Components[topGroupIndex].Count - 1;
                }
                topComponentIntegrity = this.m_blockDefinition.Components[topGroupIndex].Definition.MaxIntegrity;
                this.SetTopIndex(topGroupIndex, topComponentIndex);
            }
            this.Integrity        -= unmountAmount * this.GetDeconstructionEfficiency(topGroupIndex, damageItems | useDefaultDeconstructEfficiency);
            topComponentIntegrity -= unmountAmount * this.GetDeconstructionEfficiency(topGroupIndex, damageItems | useDefaultDeconstructEfficiency);
            if (topComponentIntegrity < 1.525902E-05f)
            {
                this.Integrity       += 1.525902E-05f - topComponentIntegrity;
                topComponentIntegrity = 1.525902E-05f;
            }
        }
Example #3
0
        public void ResetBall()
        {
            var entities        = GetEntities();
            var floatingObjects = GetEntitiesOfType <MyFloatingObject>(entities);

            entities.Clear();

            connector.ThrowOut.ValidateAndSet(false);
            var inventory = connector.GetInventoryBase();

            if (inventory.GetItemsCount() == 0)
            {
                var ores = new MyObjectBuilder_Ore()
                {
                    SubtypeName = "Iron",
                };
                inventory.AddItems(2000, ores);
            }

            foreach (var floatingObject in floatingObjects)
            {
                MyEntities.Remove(floatingObject);
            }
        }
Example #4
0
        private void AwardPoints(ZoneBlock zone, IMyFaction faction, int enemies, bool displayHeader)
        {
            if (!MyAPIGateway.Multiplayer.IsServer)
            {
                return;
            }

            string planetName = zone.GetClosestPlanet();

            if (!Planets.Any(description => description.Name == planetName))
            {
                PlanetDescription p = new PlanetDescription()
                {
                    Name   = planetName,
                    Scores = new List <ScoreDescription>()
                };

                Planets.Add(p);
            }

            long facId = faction.FactionId;
            PlanetDescription planet   = Planets.Find(w => w.Name == planetName);
            IMyCubeGrid       kothGrid = (zone.Entity as IMyCubeBlock).CubeGrid;

            if (!planet.Scores.Any(s => s.FactionId == facId))
            {
                planet.Scores.Add(new ScoreDescription()
                {
                    FactionId   = facId,
                    FactionName = faction.Name,
                    FactionTag  = faction.Tag,
                    Points      = 1,
                    PlanetId    = planetName,
                    GridName    = kothGrid.DisplayName
                });
            }

            int total = GetTotalScore(planet);
            ScoreDescription score = planet.Scores.Find(s => s.FactionId == facId);
            int current            = score.Points;

            int points;

            if (zone.PointsOnCap.Value == 0)
            {
                points = (int)(((float)(total - current) / (float)total) * 5f * enemies) + 1 + enemies;
            }
            else
            {
                points = zone.PointsOnCap.Value;
            }

            planet.Scores.Find(s => s.FactionId == facId).Points += points;
            zone.PointsEarnedSincePrize += points;


            if (zone.AwardPointsAsCredits.Value)
            {
                faction.RequestChangeBalance(points * zone.CreditsPerPoint.Value);
            }


            if (zone.PointsEarnedSincePrize >= zone.PointsForPrize.Value)
            {
                zone.PointsEarnedSincePrize -= zone.PointsForPrize.Value;

                IMyCargoContainer   prizebox = null;
                List <IMySlimBlock> temp     = new List <IMySlimBlock>();
                kothGrid.GetBlocks(temp, s => {
                    if (prizebox == null &&
                        s.FatBlock != null &&
                        s.FatBlock is IMyCargoContainer &&
                        s.FatBlock.BlockDefinition.SubtypeId == "Prizebox")
                    {
                        prizebox = s.FatBlock as IMyCargoContainer;
                    }

                    return(false);
                });

                if (zone.UseComponentReward.Value)
                {
                    string prizeType = (zone.AdvancedComponentSelection.Value) ? zone.PrizeComponentSubtypeId.Value : zone.SelectedComponentString.Value;
                    int    amount    = zone.PrizeAmountComponent.Value;

                    MyDefinitionId                definitionId  = new MyDefinitionId(typeof(MyObjectBuilder_Component), prizeType);
                    MyObjectBuilder_Component     content       = (MyObjectBuilder_Component)MyObjectBuilderSerializer.CreateNewObject(definitionId);
                    MyObjectBuilder_InventoryItem inventoryItem = new MyObjectBuilder_InventoryItem {
                        Amount = amount, Content = content
                    };

                    if (zone.SpawnIntoPrizeBox.Value)
                    {
                        if (prizebox == null)
                        {
                            Tools.Log(MyLogSeverity.Error, $"Could not find prize box on grid: {kothGrid.DisplayName} - {kothGrid.EntityId}");
                        }
                        else if (prizebox.GetInventory().CanItemsBeAdded(amount, definitionId))
                        {
                            prizebox.GetInventory().AddItems(amount, inventoryItem.Content);
                        }
                    }
                    else
                    {
                        if (zone.Entity.GetInventory().CanItemsBeAdded(amount, definitionId))
                        {
                            zone.Entity.GetInventory().AddItems(amount, inventoryItem.Content);
                        }
                    }
                }

                if (zone.UseIngotReward.Value)
                {
                    string prizeType = (zone.AdvancedIngotSelection.Value) ? zone.PrizeIngotSubtypeId.Value : zone.SelectedIngotString.Value;
                    int    amount    = zone.PrizeAmountIngot.Value;

                    MyDefinitionId                definitionId  = new MyDefinitionId(typeof(MyObjectBuilder_Ingot), prizeType);
                    MyObjectBuilder_Ingot         content       = (MyObjectBuilder_Ingot)MyObjectBuilderSerializer.CreateNewObject(definitionId);
                    MyObjectBuilder_InventoryItem inventoryItem = new MyObjectBuilder_InventoryItem {
                        Amount = amount, Content = content
                    };

                    if (zone.SpawnIntoPrizeBox.Value)
                    {
                        if (prizebox == null)
                        {
                            Tools.Log(MyLogSeverity.Error, $"Could not find prize box on grid: {kothGrid.DisplayName} - {kothGrid.EntityId}");
                        }
                        else if (prizebox.GetInventory().CanItemsBeAdded(amount, definitionId))
                        {
                            prizebox.GetInventory().AddItems(amount, inventoryItem.Content);
                        }
                    }
                    else
                    {
                        if (zone.Entity.GetInventory().CanItemsBeAdded(amount, definitionId))
                        {
                            zone.Entity.GetInventory().AddItems(amount, inventoryItem.Content);
                        }
                    }
                }

                if (zone.UseOreReward.Value)
                {
                    string prizeType = (zone.AdvancedOreSelection.Value) ? zone.PrizeOreSubtypeId.Value : zone.SelectedOreString.Value;
                    int    amount    = zone.PrizeAmountOre.Value;

                    MyDefinitionId                definitionId  = new MyDefinitionId(typeof(MyObjectBuilder_Ore), prizeType);
                    MyObjectBuilder_Ore           content       = (MyObjectBuilder_Ore)MyObjectBuilderSerializer.CreateNewObject(definitionId);
                    MyObjectBuilder_InventoryItem inventoryItem = new MyObjectBuilder_InventoryItem {
                        Amount = amount, Content = content
                    };

                    if (zone.SpawnIntoPrizeBox.Value)
                    {
                        if (prizebox == null)
                        {
                            Tools.Log(MyLogSeverity.Error, $"Could not find prize box on grid: {kothGrid.DisplayName} - {kothGrid.EntityId}");
                        }
                        else if (prizebox.GetInventory().CanItemsBeAdded(amount, definitionId))
                        {
                            prizebox.GetInventory().AddItems(amount, inventoryItem.Content);
                        }
                    }
                    else
                    {
                        if (zone.Entity.GetInventory().CanItemsBeAdded(amount, definitionId))
                        {
                            zone.Entity.GetInventory().AddItems(amount, inventoryItem.Content);
                        }
                    }
                }
            }

            StringBuilder message = new StringBuilder();

            if (displayHeader && zone.IsLocationNamed.Value)
            {
                if (zone.EncampmentMode.Value)
                {
                    message.Append($"{kothGrid.DisplayName} on {planetName} Encampment Payout");
                }
                else
                {
                    message.Append($"{kothGrid.DisplayName} on {planetName} under attack");
                }
            }

            byte[] bytes = Encoding.ASCII.GetBytes(message.ToString());
            MyAPIGateway.Multiplayer.SendMessageToServer(8008, bytes);
            Network.Say(message.ToString());

            message.Clear();
            if (zone.AwardPointsAsCredits.Value)
            {
                message.Append($"{faction.Name} Scored {points} Points! ({points * zone.CreditsPerPoint.Value} credits)");
            }
            else
            {
                message.Append($"{faction.Name} Scored {points} Points!");
            }


            SaveData();

            //NEXUS: if nexus is initialized, broadcast the message to nexus (and all other sectors in that way)
            //NEXUS: KotH should work normally if nexus is not initialized
            if (nexusInit)
            {
                //NEXUS: sends the message this sector displays in the chat to all the other sectors
                byte[] nexMessage = Encoding.ASCII.GetBytes(message.ToString());
                Nexus.SendMessageToAllServers(nexMessage);

                //NEXUS: score is broadcasted to other sectors, this basically triggers the save not just on this sector but on all the others with the same score
                var serializedScore = MyAPIGateway.Utilities.SerializeToBinary <List <PlanetDescription> >(Planets);
                Nexus2.SendMessageToAllServers(serializedScore);
            }

            bytes = Encoding.ASCII.GetBytes(message.ToString());
            MyAPIGateway.Multiplayer.SendMessageToServer(8008, bytes);
            Network.Say(message.ToString());
        }
Example #5
0
        /// <summary>
        /// Find the physical object of the specified name or partial name.
        /// </summary>
        /// <param name="itemName">The name of the physical object to find.</param>
        /// <param name="objectBuilder">The object builder of the physical object, ready for use.</param>
        /// <param name="options">Returns a list of potential matches if there was more than one of the same or partial name.</param>
        /// <returns>Returns true if a single exact match was found.</returns>

        public static bool FindPhysicalParts(string itemName, out MyObjectBuilder_Base objectBuilder, out Dictionary <string, MyDefinitionBase> options)
        {
            BuildComponentLists();
            itemName = itemName.Trim();
            var itemNames = itemName.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            // prefix the search term with 'ore' to find this ore name.
            if (itemNames.Length > 1 && itemNames[0].Equals("ore", StringComparison.InvariantCultureIgnoreCase))
            {
                var findName = itemName.Substring(4).Trim();

                var exactMatchOres = _oreList.Where(ore => ore.Value.Id.SubtypeName.Equals(findName, StringComparison.InvariantCultureIgnoreCase)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                if (exactMatchOres.Count == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ore()
                    {
                        SubtypeName = exactMatchOres.First().Value.Id.SubtypeName
                    };
                    options = new Dictionary <string, MyDefinitionBase>();
                    return(true);
                }
                if (exactMatchOres.Count > 1)
                {
                    objectBuilder = null;
                    options       = exactMatchOres;
                    return(false);
                }

                var partialMatchOres = _oreList.Where(ore => ore.Value.Id.SubtypeName.IndexOf(findName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                if (partialMatchOres.Count == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ore()
                    {
                        SubtypeName = partialMatchOres.First().Value.Id.SubtypeName
                    };
                    options = new Dictionary <string, MyDefinitionBase>();
                    return(true);
                }
                if (partialMatchOres.Count > 1)
                {
                    objectBuilder = null;
                    options       = partialMatchOres;
                    return(false);
                }

                objectBuilder = null;
                options       = new Dictionary <string, MyDefinitionBase>();
                return(false);
            }

            // prefix the search term with 'ingot' to find this ingot name.
            if (itemNames.Length > 1 && itemNames[0].Equals("ingot", StringComparison.InvariantCultureIgnoreCase))
            {
                var findName = itemName.Substring(6).Trim();

                var exactMatchIngots = _ingotList.Where(ingot => ingot.Value.Id.SubtypeName.Equals(findName, StringComparison.InvariantCultureIgnoreCase)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                if (exactMatchIngots.Count == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ingot()
                    {
                        SubtypeName = exactMatchIngots.First().Value.Id.SubtypeName
                    };
                    options = new Dictionary <string, MyDefinitionBase>();
                    return(true);
                }
                if (exactMatchIngots.Count > 1)
                {
                    objectBuilder = null;
                    options       = exactMatchIngots;
                    return(false);
                }

                var partialMatchIngots = _ingotList.Where(ingot => ingot.Value.Id.SubtypeName.IndexOf(findName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                if (partialMatchIngots.Count == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ingot()
                    {
                        SubtypeName = partialMatchIngots.First().Value.Id.SubtypeName
                    };
                    options = new Dictionary <string, MyDefinitionBase>();
                    return(true);
                }
                if (partialMatchIngots.Count > 1)
                {
                    objectBuilder = null;
                    options       = partialMatchIngots;
                    return(false);
                }

                objectBuilder = null;
                options       = new Dictionary <string, MyDefinitionBase>();
                return(false);
            }

            // full name match.
            var res = _physicalItemNames.FirstOrDefault(s => s.Key != null && s.Key.Equals(itemName, StringComparison.InvariantCultureIgnoreCase));

            // need a good method for finding partial name matches.
            if (res.Key == null)
            {
                var matches = _physicalItemNames.Where(s => s.Key != null && s.Key.StartsWith(itemName, StringComparison.InvariantCultureIgnoreCase)).Distinct().ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

                if (matches.Count == 1)
                {
                    res = matches.FirstOrDefault();
                }
                else
                {
                    matches = _physicalItemNames.Where(s => s.Key != null && s.Key.IndexOf(itemName, StringComparison.InvariantCultureIgnoreCase) >= 0).Distinct().ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                    if (matches.Count == 1)
                    {
                        res = matches.FirstOrDefault();
                    }
                    else if (matches.Count > 1)
                    {
                        objectBuilder = null;
                        options       = matches;
                        return(false);
                    }
                }
            }

            if (res.Key != null)
            {
                if (res.Value != null)
                {
                    objectBuilder = MyObjectBuilderSerializer.CreateNewObject(res.Value.Id.TypeId, res.Value.Id.SubtypeName);
                    options       = new Dictionary <string, MyDefinitionBase>();
                    return(true);
                }
            }

            objectBuilder = null;
            options       = new Dictionary <string, MyDefinitionBase>();
            return(false);
        }
Example #6
0
            //      public static bool TestPatchMethod2(MyDrillBase __instance, MyDrillSensorBase.DetectionInfo entry,
            //bool collectOre,
            //bool performCutout,
            //bool assignDamagedMaterial,
            //ref MyStringHash targetMaterial)
            //      {
            //        //  return false;
            //          if (__instance.OutputInventory.Owner.GetBaseEntity() is MyShipDrill drill)
            //          {
            //              MyVoxelBase entity = entry.Entity as MyVoxelBase;
            //              Vector3D worldPosition = entry.DetectionPoint;
            //              bool flag1 = false;
            //              int count = 0;
            //              CrunchUtilitiesPlugin.Log.Info(count + "");
            //              count++;


            //                  CrunchUtilitiesPlugin.Log.Info(count + "");
            //                  count++;
            //                  MyVoxelMaterialDefinition material = (MyVoxelMaterialDefinition)null;
            //                  Vector3D center = __instance.CutOut.Sphere.Center;
            //                  MatrixD worldMatrix = drill.WorldMatrix;
            //                  Vector3D forward = worldMatrix.Forward;
            //                  Vector3D from = center - forward;
            //                  worldMatrix = drill.WorldMatrix;
            //                  CrunchUtilitiesPlugin.Log.Info(count + "");
            //                  count++;
            //                  MyPhysics.CastRay(from, from + worldMatrix.Forward * (__instance.CutOut.Sphere.Center + 1.0), m_castList, 28);
            //                  CrunchUtilitiesPlugin.Log.Info(count + "");
            //                  count++;
            //                  bool flag2 = false;
            //                  CrunchUtilitiesPlugin.Log.Info(count + "");
            //                  count++;
            //                  foreach (MyPhysics.HitInfo cast in m_castList)
            //                  {
            //                      CrunchUtilitiesPlugin.Log.Info(count + "");
            //                      count++;
            //                      if (cast.HkHitInfo.GetHitEntity() is MyVoxelBase)
            //                      {
            //                          worldPosition = cast.Position;
            //                      MyVoxelMaterialDefinition material2;

            //                          material2 = entity.GetMaterialAt(ref worldPosition);
            //                      if (material2 == null)
            //                      {

            //                      }
            //                      MyObjectBuilder_Ore newObject = MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_Ore>(material2.MinedOre);
            //                      if (!newObject.SubtypeName.ToLower().Contains("stone"))
            //                      {
            //                          material = material2;
            //                          flag2 = true;
            //                          break;
            //                      }
            //                      }
            //                  }
            //                  if (material == null)
            //              {
            //                  return false;
            //              }
            //                  CrunchUtilitiesPlugin.Log.Info(count + "");
            //                  count++;
            //                  MyObjectBuilder_Ore newObject2 = MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_Ore>(material.MinedOre);
            //                  if (newObject2.SubtypeName.ToLower().Contains("stone"))
            //                  {
            //                      CrunchUtilitiesPlugin.Log.Info("It be stone");
            //                      return false;
            //                  }
            //                  return true;

            //          }
            //          return true;
            //      }
            public static bool TestPatchMethod(MyDrillBase __instance, MyVoxelMaterialDefinition material, Vector3 hitPosition)
            {
                if (file != null && !file.DeleteStoneAuto)
                {
                    return(true);
                }
                if (string.IsNullOrEmpty(material.MinedOre))
                {
                    return(false);
                }
                List <IMyEntity> l = new List <IMyEntity>();

                if (__instance.OutputInventory == null || __instance.OutputInventory.Owner == null || __instance.OutputInventory.Owner.GetBaseEntity() == null)
                {
                    return(true);
                }
                if (__instance.OutputInventory != null && __instance.OutputInventory.Owner != null)
                {
                    if (__instance.OutputInventory.Owner.GetBaseEntity() is MyShipDrill drill)
                    {
                        if (drill == null)
                        {
                            return(true);
                        }


                        if (drill.DisplayNameText != null && containsName(drill.DisplayNameText))
                        {
                            MyObjectBuilder_Ore newObject = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_Ore>(material.MinedOre);
                            if (newObject.SubtypeName.ToLower().Contains("stone"))
                            {
                                //if (file.UsingDraconisEliteDrills)
                                //{
                                //    if (!drill.BlockDefinition.BlockPairName.Equals("Drill8x"))
                                //    {
                                //        return true;
                                //    }

                                //}
                                return(false);
                            }
                        }
                        if (ids.Contains(drill.OwnerId))
                        {
                            MyObjectBuilder_Ore newObject = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_Ore>(material.MinedOre);
                            if (newObject.SubtypeName.ToLower().Contains("stone"))
                            {
                                //if (file.UsingDraconisEliteDrills)
                                //{
                                //    if (!drill.BlockDefinition.BlockPairName.Equals("Drill8x"))
                                //    {
                                //        return true;
                                //    }
                                //}
                                return(false);
                            }
                        }
                        else
                        {
                            return(true);
                        }
                    }
                }
                return(true);
            }
        protected override IEnumerator <bool> ProcessVoxels(HashSet <IMyVoxelBase> Voxels)
        {
            if (!MyKernel.Session.Settings.EnableDrilling)
            {
                yield return(false);
            }
            if (Voxels.Count == 0)
            {
                yield return(false);
            }
            if (MyKernel.TermControls.ToolMode == true)
            {
                yield return(false);
            }
            if (!SafeZonesHelper.IsActionAllowed(MyKernel.Block.GetPosition(), MySafeZoneAction.Drilling, MyKernel.Block.EntityId))
            {
                yield return(false);
            }
            //WriteToLog("ProcessVoxels", $"Processing {Voxels.Count} voxels");
            Stopwatch stopwatch  = Stopwatch.StartNew();
            LineD     WorkingRay = new LineD(MyKernel.BeamDrawer.BeamStart, MyKernel.BeamDrawer.BeamEnd);

            foreach (MyVoxelBase Voxel in Voxels.OfType <MyVoxelBase>())
            {
                if (!SafeZonesHelper.IsActionAllowed((Voxel as IMyEntity).WorldAABB, MySafeZoneAction.Drilling, MyKernel.Block.EntityId))
                {
                    continue;
                }
                if (Voxel.GetOrePriority() == -1)
                {
                    continue;                               // Idk why, but the same early exit is found in MyShipDrill
                }
                Vector3D?VoxelHit = Voxel.GetClosestPointOnRay(WorkingRay, step: 0.99f);
                if (VoxelHit.HasValue)
                {
                    MyKernel.ResponderModule.UpdateStatusReport($"\r\nFound a voxel", true);
                    lock (BlockedVoxels)
                    {
                        if (!BlockedVoxels.ContainsKey(Voxel.EntityId))
                        {
                            BlockedVoxels.Add(Voxel.EntityId, new List <Vector3I>());
                        }
                    }
                    Vector3D hitpos = VoxelHit.Value;
                    //MyVoxelMaterialDefinition Material = Voxel.GetMaterialAt(ref hitpos);
                    Vector3D CutoutSphereCenter = hitpos + (-WorkingRay.Direction * DrillingOffsetM);
                    //stopwatch.Stop();
                    //WriteToLog("ProcessVoxels", $"Hit: {Math.Round(Vector3D.Distance(WorkingRay.From, hitpos), 2)}m, cutout: {Math.Round(Vector3D.Distance(WorkingRay.From, CutoutSphereCenter), 2)} m away, Material: {(Material != null ? Material.MaterialTypeName : "null")}");
                    //stopwatch.Start();

                    BoundingSphereD Cutout = new BoundingSphereD(CutoutSphereCenter, CutoutRadius);

                    //List<Vector3I> VoxelPoints = Voxel.GetVoxelPointsInSphere(Cutout);
                    Vector3I      refCorner;
                    Vector3I      refMaxCorner;
                    MyStorageData cutoutVoxels = Voxel.GetVoxelCacheInSphere(Cutout, out refCorner, out refMaxCorner);
                    //WriteToLog("ProcessVoxels", $"Cutout cache Min is {Math.Round(Vector3D.Distance(hitpos, Voxel.PositionLeftBottomCorner + refCorner), 2)}m away");
                    //WriteToLog("ProcessVoxels", $"Cutout cache Max is {Math.Round(Vector3D.Distance(hitpos, Voxel.PositionLeftBottomCorner + refCorner + cutoutVoxels.Size3D), 2)}m away");
                    Dictionary <MyVoxelMaterialDefinition, float> Materials = new Dictionary <MyVoxelMaterialDefinition, float>();

                    int       nullMaterials   = 0;
                    int       totalPoints     = 0;
                    Stopwatch enumeratorWatch = new Stopwatch();
                    using (MyStorageData.MortonEnumerator VoxelLoop = new MyStorageData.MortonEnumerator(cutoutVoxels, MyStorageDataTypeEnum.Content | MyStorageDataTypeEnum.Material))
                    {
                        MyKernel.ResponderModule.UpdateStatusReport($"Entered enumerator", true);
                        enumeratorWatch.Start();
                        Dictionary <byte, float> RawMaterials = new Dictionary <byte, float>();
                        Vector3I VoxelInSphereCenter;
                        Vector3  CoordsSystemOutValue;
                        //MyVoxelCoordSystems.WorldPositionToLocalPosition(Cutout.Center, Voxel.PositionComp.WorldMatrix, Voxel.PositionComp.WorldMatrixInvScaled, Voxel.SizeInMetresHalf, out CoordsSystemOutValue);
                        //VoxelInSphereCenter = new Vector3I(CoordsSystemOutValue / 1f) + Voxel.StorageMin;
                        Vector3D sphereCenter = Cutout.Center;
                        MyVoxelCoordSystems.WorldPositionToLocalPosition(Voxel.PositionLeftBottomCorner, ref sphereCenter, out CoordsSystemOutValue);
                        VoxelInSphereCenter = new Vector3I(CoordsSystemOutValue / 1f) + Voxel.StorageMin;
                        Vector3D ReconstructedPosition = Voxel.PositionLeftBottomCorner + VoxelInSphereCenter;
                        //WriteToLog("ProcessVoxels", $"VoxelInSphereCenter is {Math.Round(Vector3D.Distance(hitpos, ReconstructedPosition), 2)}m away from hitpos");
                        double CutoutRadiusSquared = Cutout.Radius * Cutout.Radius;

                        int processedPoints = 0;
                        int skippedPoints   = 0;
                        int linearIndex     = -1;
                        for (bool move = true; move != false;)
                        {
                            enumeratorWatch.Start();
                            try
                            {
                                move = VoxelLoop.MoveNext();
                            }
                            catch
                            {
                                move = false;
                                MyKernel.ResponderModule.UpdateStatusReport("Keen enumerator died", true);
                            }
                            if (move)
                            {
                                linearIndex++;
                                Vector3I voxelPoint;
                                cutoutVoxels.ComputePosition(linearIndex, out voxelPoint);
                                voxelPoint += refCorner;
                                BoundingBoxD voxelBox = new BoundingBoxD(Voxel.PositionLeftBottomCorner + voxelPoint, Voxel.PositionLeftBottomCorner + voxelPoint + 1);

                                var  PointContainment = Cutout.Contains(voxelBox);
                                bool Contacts         = PointContainment.HasFlag(ContainmentType.Contains) || PointContainment.HasFlag(ContainmentType.Intersects);
                                if (Contacts || Vector3D.DistanceSquared(ReconstructedPosition, Voxel.PositionLeftBottomCorner + voxelPoint) <= CutoutRadiusSquared)
                                {
                                    bool pointBlocked = true;
                                    lock (BlockedVoxels)
                                    {
                                        pointBlocked = BlockedVoxels[Voxel.EntityId].Contains(voxelPoint);
                                        if (!pointBlocked)
                                        {
                                            BlockedVoxels[Voxel.EntityId].Add(voxelPoint);
                                        }
                                    }
                                    if (!pointBlocked)
                                    {
                                        byte  ContentFillLevel  = cutoutVoxels.Content(linearIndex);
                                        byte  MaterialId        = cutoutVoxels.Material(linearIndex);
                                        float MaterialFillRatio = ContentFillLevel / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT;

                                        if (!RawMaterials.ContainsKey(MaterialId))
                                        {
                                            RawMaterials.Add(MaterialId, MaterialFillRatio);
                                        }
                                        else
                                        {
                                            RawMaterials[MaterialId] += MaterialFillRatio;
                                        }

                                        processedPoints++;
                                    }
                                    else
                                    {
                                        skippedPoints++;
                                    }
                                }
                                else
                                {
                                    skippedPoints++;
                                }

                                int voxelIterationLimit = MyKernel.Session.Settings.SpeedMultiplierAcceleratesDrilling ? VoxelIterationLimit * MyKernel.TermControls.SpeedMultiplier : VoxelIterationLimit;
                                if (processedPoints > 0 && processedPoints % voxelIterationLimit == 0)
                                {
                                    //MyKernel.ResponderModule.UpdateStatusReport($"Cutting out {Math.Round(Cutout.Radius * 2, 1)}m sphere:\r\n{linearIndex} voxels processed", append: true);
                                    enumeratorWatch.Stop();
                                    yield return(true);
                                }
                            }
                            totalPoints = linearIndex;
                        }
                        MyKernel.ResponderModule.UpdateStatusReport($"Total processed points: {totalPoints} ({processedPoints}/{skippedPoints})", true);
                        enumeratorWatch.Stop();
                        MyKernel.ResponderModule.UpdateStatusReport($"EnumeratorWatch: {Math.Round(enumeratorWatch.Elapsed.TotalMilliseconds, 3)}ms", true);
                        //WriteToLog("ProcessVoxels", $"Found {processedPoints} valid voxel points out of {totalPoints}", EemRdx.SessionModules.LoggingLevelEnum.DebugLog, true, 2000);

                        foreach (KeyValuePair <byte, float> kvp in RawMaterials)
                        {
                            MyVoxelMaterialDefinition material = MyDefinitionManager.Static.GetVoxelMaterialDefinition(kvp.Key);
                            if (material != null)
                            {
                                Materials.Add(material, kvp.Value * DrillingYield);
                            }
                            else
                            {
                                nullMaterials++;
                                continue;
                            }
                        }
                    }
                    MyKernel.ResponderModule.UpdateStatusReport($"Quitted enumerator", true);
                    //WriteToLog("ProcessVoxels", $"Found {VoxelPoints.Count} valid voxel points", EemRdx.SessionModules.LoggingLevelEnum.DebugLog, true, 2000);
                    //WriteToLog("ProcessVoxels", $"Found {Materials.Count} valid materials{(nullMaterials > 0 ? $" and {nullMaterials} null materials" : "")}", EemRdx.SessionModules.LoggingLevelEnum.DebugLog, true, 2000);
                    //foreach (var kvp in Materials)
                    //{
                    //    WriteToLog("ProcessVoxels", $"Material: {kvp.Key.MaterialTypeName} (mined ore: {(kvp.Key.MinedOre != null ? kvp.Key.MinedOre : "null")}), amount: {kvp.Value}");
                    //}

                    MyKernel.ResponderModule.UpdateStatusReport($"Calculating materials", true);
                    Dictionary <MyObjectBuilder_Ore, float> MaterialsToAdd = new Dictionary <MyObjectBuilder_Ore, float>();
                    int nullMinedOres = 0;
                    foreach (KeyValuePair <MyVoxelMaterialDefinition, float> kvp in Materials)
                    {
                        MyVoxelMaterialDefinition material = kvp.Key;
                        if (string.IsNullOrWhiteSpace(material.MinedOre))
                        {
                            nullMinedOres++;
                            continue;
                        }
                        try
                        {
                            if (MyKernel.TermControls.DumpStone && material.MinedOre == "Stone")
                            {
                                continue;
                            }
                            MyObjectBuilder_Ore oreBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_Ore>(material.MinedOre);
                            oreBuilder.MaterialTypeName = new MyStringHash?(material.Id.SubtypeId);
                            MyPhysicalItemDefinition oreDef = MyDefinitionManager.Static.GetPhysicalItemDefinition(oreBuilder);
                            float MinedAmountInKg           = (kvp.Value / 1000 / oreDef.Volume) * oreDef.Mass * kvp.Key.MinedOreRatio * 32;
                            stopwatch.Stop();
                            //WriteToLog("ProcessVoxels", $"Found material {material.MaterialTypeName}, {Math.Round(kvp.Value)} points, mined amount would be {Math.Round(MinedAmountInKg)} kg");
                            stopwatch.Start();
                            MaterialsToAdd.Add(oreBuilder, MinedAmountInKg);
                        }
                        catch (Exception Scrap)
                        {
                            LogError("ProcessVoxels().dict_Materials.Iterate", $"Unknown error occurred on material {material.MinedOre}", Scrap);
                        }
                    }

                    Stopwatch cutoutWatch = Stopwatch.StartNew();
                    //Voxel.Storage.WriteRange(cutoutVoxels, MyStorageDataTypeFlags.ContentAndMaterial, refCorner - 1, refMaxCorner + 1);
                    Voxel.RootVoxel.PerformCutOutSphereFast(Cutout.Center, (float)Cutout.Radius, true);
                    cutoutWatch.Stop();
                    //WriteToLog("ProcessVoxels", $"Sphere was cut in {cutoutWatch.ElapsedTicks} ticks, which is {Math.Round(cutoutWatch.Elapsed.TotalMilliseconds, 4)} ms");

                    foreach (var kvp in MaterialsToAdd)
                    {
                        MyDefinitionId OreId       = kvp.Key.GetId();
                        MyItemType     oreItemType = new MyItemType(OreId.TypeId, OreId.SubtypeId);
                        float          amountToAdd = kvp.Value;
                        while (amountToAdd > 0.1f)
                        {
                            while (((float)ToolCargo.CurrentVolume / (float)ToolCargo.MaxVolume) > 0.9f)
                            {
                                yield return(true);
                            }

                            MyInventoryItem oreItem       = new MyInventoryItem(oreItemType, 0, (VRage.MyFixedPoint)amountToAdd);
                            float           FittingAmount = (float)(ToolCargo as Sandbox.Game.MyInventory).ComputeAmountThatFits(OreId);
                            if (FittingAmount > amountToAdd)
                            {
                                FittingAmount = amountToAdd;
                            }
                            ToolCargo.AddItems((VRage.MyFixedPoint)FittingAmount, kvp.Key);
                            amountToAdd -= FittingAmount;
                            //MyKernel.ResponderModule.UpdateStatusReport($"Adding {Math.Round(FittingAmount)}u of {OreId.SubtypeId}, {amountToAdd} remains", append: false);
                        }
                    }
                }
                else
                {
                    MyKernel.ResponderModule.UpdateStatusReport($"No voxel found", true);
                }
            }
            stopwatch.Stop();
            double ElapsedMs = stopwatch.Elapsed.TotalMilliseconds;

            //WriteToLog("ProcessVoxels", $"Voxels processed, elapsed time: {stopwatch.ElapsedTicks} ticks, which is {Math.Round(ElapsedMs, 3)} ms");
            MyKernel.ResponderModule.UpdateStatusReport($"Cycle finished", true);
            yield return(false);
        }
        /// <summary>
        /// Find the physical object of the specified name or partial name.
        /// </summary>
        /// <param name="itemName">The name of the physical object to find.</param>
        /// <param name="objectBuilder">The object builder of the physical object, ready for use.</param>
        /// <param name="options">Returns a list of potential matches if there was more than one of the same or partial name.</param>
        /// <returns>Returns true if a single exact match was found.</returns>
        public static bool FindPhysicalParts(string[] _oreNames, string[] _ingotNames, string[] _physicalItemNames, MyPhysicalItemDefinition[] _physicalItems, string itemName, out MyObjectBuilder_Base objectBuilder, out string[] options)
        {
            var itemNames = itemName.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            // prefix the search term with 'ore' to find this ore name.
            if (itemNames.Length > 1 && itemNames[0].Equals("ore", StringComparison.InvariantCultureIgnoreCase))
            {
                var findName = itemName.Substring(4).Trim();

                var exactMatchOres = _oreNames.Where(ore => ore.Equals(findName, StringComparison.InvariantCultureIgnoreCase)).ToArray();
                if (exactMatchOres.Length == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ore() { SubtypeName = exactMatchOres[0] };
                    options = new string[0];
                    return true;
                }
                else if (exactMatchOres.Length > 1)
                {
                    objectBuilder = null;
                    options = exactMatchOres;
                    return false;
                }

                var partialMatchOres = _oreNames.Where(ore => ore.IndexOf(findName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToArray();
                if (partialMatchOres.Length == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ore() { SubtypeName = partialMatchOres[0] };
                    options = new string[0];
                    return true;
                }
                else if (partialMatchOres.Length > 1)
                {
                    objectBuilder = null;
                    options = partialMatchOres;
                    return false;
                }

                objectBuilder = null;
                options = new string[0];
                return false;
            }

            // prefix the search term with 'ingot' to find this ingot name.
            if (itemNames.Length > 1 && itemNames[0].Equals("ingot", StringComparison.InvariantCultureIgnoreCase))
            {
                var findName = itemName.Substring(6).Trim();

                var exactMatchIngots = _ingotNames.Where(ingot => ingot.Equals(findName, StringComparison.InvariantCultureIgnoreCase)).ToArray();
                if (exactMatchIngots.Length == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ingot() { SubtypeName = exactMatchIngots[0] };
                    options = new string[0];
                    return true;
                }
                else if (exactMatchIngots.Length > 1)
                {
                    objectBuilder = null;
                    options = exactMatchIngots;
                    return false;
                }

                var partialMatchIngots = _ingotNames.Where(ingot => ingot.IndexOf(findName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToArray();
                if (partialMatchIngots.Length == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ingot() { SubtypeName = partialMatchIngots[0] };
                    options = new string[0];
                    return true;
                }
                else if (partialMatchIngots.Length > 1)
                {
                    objectBuilder = null;
                    options = partialMatchIngots;
                    return false;
                }

                objectBuilder = null;
                options = new string[0];
                return false;
            }

            // full name match.
            var res = _physicalItemNames.FirstOrDefault(s => s != null && s.Equals(itemName, StringComparison.InvariantCultureIgnoreCase));

            // need a good method for finding partial name matches.
            if (res == null)
            {
                var matches = _physicalItemNames.Where(s => s != null && s.StartsWith(itemName, StringComparison.InvariantCultureIgnoreCase)).Distinct().ToArray();

                if (matches.Length == 1)
                {
                    res = matches.FirstOrDefault();
                }
                else
                {
                    matches = _physicalItemNames.Where(s => s != null && s.IndexOf(itemName, StringComparison.InvariantCultureIgnoreCase) >= 0).Distinct().ToArray();
                    if (matches.Length == 1)
                    {
                        res = matches.FirstOrDefault();
                    }
                    else if (matches.Length > 1)
                    {
                        objectBuilder = null;
                        options = matches;
                        return false;
                    }
                }
            }

            if (res != null)
            {
                var item = _physicalItems[Array.IndexOf(_physicalItemNames, res)];
                if (item != null)
                {
                    objectBuilder = MyObjectBuilderSerializer.CreateNewObject(item.Id.TypeId, item.Id.SubtypeName);
                    options = new string[0];
                    return true;
                }
            }

            objectBuilder = null;
            options = new string[0];
            return false;
        }
Example #9
0
        /// <summary>
        /// Find the physical object of the specified name or partial name.
        /// </summary>
        /// <param name="itemName">The name of the physical object to find.</param>
        /// <param name="objectBuilder">The object builder of the physical object, ready for use.</param>
        /// <param name="options">Returns a list of potential matches if there was more than one of the same or partial name.</param>
        /// <returns>Returns true if a single exact match was found.</returns>
        public static bool FindPhysicalParts(string itemName, out MyObjectBuilder_Base objectBuilder, out Dictionary<string, MyPhysicalItemDefinition> options)
        {
            BuildComponentLists();
            itemName = itemName.Trim();
            var itemNames = itemName.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            // prefix the search term with 'ore' to find this ore name.
            if (itemNames.Length > 1 && itemNames[0].Equals("ore", StringComparison.InvariantCultureIgnoreCase))
            {
                var findName = itemName.Substring(4).Trim();

                var exactMatchOres = _oreList.Where(ore => ore.Value.Id.SubtypeName.Equals(findName, StringComparison.InvariantCultureIgnoreCase)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                if (exactMatchOres.Count == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ore() { SubtypeName = exactMatchOres.First().Value.Id.SubtypeName };
                    options = new Dictionary<string, MyPhysicalItemDefinition>();
                    return true;
                }
                if (exactMatchOres.Count > 1)
                {
                    objectBuilder = null;
                    options = exactMatchOres;
                    return false;
                }

                var partialMatchOres = _oreList.Where(ore => ore.Value.Id.SubtypeName.IndexOf(findName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                if (partialMatchOres.Count == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ore() { SubtypeName = partialMatchOres.First().Value.Id.SubtypeName };
                    options = new Dictionary<string, MyPhysicalItemDefinition>();
                    return true;
                }
                if (partialMatchOres.Count > 1)
                {
                    objectBuilder = null;
                    options = partialMatchOres;
                    return false;
                }

                objectBuilder = null;
                options = new Dictionary<string, MyPhysicalItemDefinition>();
                return false;
            }

            // prefix the search term with 'ingot' to find this ingot name.
            if (itemNames.Length > 1 && itemNames[0].Equals("ingot", StringComparison.InvariantCultureIgnoreCase))
            {
                var findName = itemName.Substring(6).Trim();

                var exactMatchIngots = _ingotList.Where(ingot => ingot.Value.Id.SubtypeName.Equals(findName, StringComparison.InvariantCultureIgnoreCase)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                if (exactMatchIngots.Count == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ingot() { SubtypeName = exactMatchIngots.First().Value.Id.SubtypeName };
                    options = new Dictionary<string, MyPhysicalItemDefinition>();
                    return true;
                }
                if (exactMatchIngots.Count > 1)
                {
                    objectBuilder = null;
                    options = exactMatchIngots;
                    return false;
                }

                var partialMatchIngots = _ingotList.Where(ingot => ingot.Value.Id.SubtypeName.IndexOf(findName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                if (partialMatchIngots.Count == 1)
                {
                    objectBuilder = new MyObjectBuilder_Ingot() { SubtypeName = partialMatchIngots.First().Value.Id.SubtypeName };
                    options = new Dictionary<string, MyPhysicalItemDefinition>();
                    return true;
                }
                if (partialMatchIngots.Count > 1)
                {
                    objectBuilder = null;
                    options = partialMatchIngots;
                    return false;
                }

                objectBuilder = null;
                options = new Dictionary<string, MyPhysicalItemDefinition>();
                return false;
            }

            // full name match.
            var res = _physicalItemNames.FirstOrDefault(s => s.Key != null && s.Key.Equals(itemName, StringComparison.InvariantCultureIgnoreCase));

            // need a good method for finding partial name matches.
            if (res.Key == null)
            {
                var matches = _physicalItemNames.Where(s => s.Key != null && s.Key.StartsWith(itemName, StringComparison.InvariantCultureIgnoreCase)).Distinct().ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

                if (matches.Count == 1)
                {
                    res = matches.FirstOrDefault();
                }
                else
                {
                    matches = _physicalItemNames.Where(s => s.Key != null && s.Key.IndexOf(itemName, StringComparison.InvariantCultureIgnoreCase) >= 0).Distinct().ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                    if (matches.Count == 1)
                    {
                        res = matches.FirstOrDefault();
                    }
                    else if (matches.Count > 1)
                    {
                        objectBuilder = null;
                        options = matches;
                        return false;
                    }
                }
            }

            if (res.Key != null)
            {
                if (res.Value != null)
                {
                    objectBuilder = MyObjectBuilderSerializer.CreateNewObject(res.Value.Id.TypeId, res.Value.Id.SubtypeName);
                    options = new Dictionary<string, MyPhysicalItemDefinition>();
                    return true;
                }
            }

            objectBuilder = null;
            options = new Dictionary<string, MyPhysicalItemDefinition>();
            return false;
        }
Example #10
0
        public static void TestPatchMethod(MyDrillBase __instance, MyVoxelMaterialDefinition material,
                                           VRageMath.Vector3 hitPosition,
                                           int removedAmount,
                                           bool onlyCheck)
        {
            if (__instance.OutputInventory != null && __instance.OutputInventory.Owner != null)
            {
                if (__instance.OutputInventory.Owner.GetBaseEntity() is MyShipDrill shipDrill)
                {
                    if (drill == null)
                    {
                        drill = __instance.GetType();
                    }

                    if (string.IsNullOrEmpty(material.MinedOre))
                    {
                        return;
                    }

                    if (!onlyCheck)
                    {
                        long playerId    = 0;
                        bool HasContract = false;
                        foreach (IMyCockpit cockpit in shipDrill.CubeGrid.GetFatBlocks().OfType <IMyCockpit>())
                        {
                            if (cockpit.Pilot != null)
                            {
                                MyCharacter pilot = cockpit.Pilot as MyCharacter;
                                if (playerWithContract.ContainsKey(pilot.GetPlayerIdentityId()))
                                {
                                    PlayerStorage storage = playerWithContract[pilot.GetPlayerIdentityId()];
                                    if (storage.CheckIfInMiningArea(hitPosition, material.MinedOre))
                                    {
                                        playerId    = pilot.GetPlayerIdentityId();
                                        HasContract = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (!HasContract)
                        {
                            return;
                        }


                        MyObjectBuilder_Ore newObject = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_Ore>(material.MinedOre);
                        newObject.MaterialTypeName = new MyStringHash?(material.Id.SubtypeId);
                        float num = (float)((double)removedAmount / (double)byte.MaxValue * 1.0) * __instance.VoxelHarvestRatio * material.MinedOreRatio;
                        if (!MySession.Static.AmountMined.ContainsKey(material.MinedOre))
                        {
                            MySession.Static.AmountMined[material.MinedOre] = (MyFixedPoint)0;
                        }
                        MySession.Static.AmountMined[material.MinedOre] += (MyFixedPoint)num;
                        MyPhysicalItemDefinition physicalItemDefinition = MyDefinitionManager.Static.GetPhysicalItemDefinition((MyObjectBuilder_Base)newObject);
                        MyFixedPoint             amountItems1           = (MyFixedPoint)(num / physicalItemDefinition.Volume);
                        MyFixedPoint             maxAmountPerDrop       = (MyFixedPoint)(float)(0.150000005960464 / (double)physicalItemDefinition.Volume);


                        MyFixedPoint collectionRatio = (MyFixedPoint)drill.GetField("m_inventoryCollectionRatio", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance);
                        MyFixedPoint b            = amountItems1 * ((MyFixedPoint)1 - collectionRatio);
                        MyFixedPoint amountItems2 = MyFixedPoint.Min(maxAmountPerDrop * 10 - (MyFixedPoint)0.001, b);
                        MyFixedPoint totalAmount  = amountItems1 * collectionRatio - amountItems2;
                        if (playerWithContract[playerId].AddToContractAmount(material.MinedOre, totalAmount.ToIntSafe()))
                        {
                            foreach (ContractHolder contractHolder in playerWithContract[playerId].MiningContracts.Values)
                            {
                                if (contractHolder.contract.subTypeId.Equals(material.MinedOre))
                                {
                                    ShipyardCommands.SendMessage("Big Boss Dave", "Contract progress :" + material.MinedOre + " " + contractHolder.minedAmount + " / " + contractHolder.amountToMine, Color.Gold, (long)MySession.Static.Players.TryGetSteamId(playerId));
                                }
                            }
                        }
                    }
                }
                else
                {
                    return;
                }
            }
        }
        private void spawnMeteor(Vector3Wrapper spawnpos, Vector3Wrapper vel, Vector3Wrapper up, Vector3Wrapper forward)
        {
            if (SandboxGameAssemblyWrapper.IsDebugging)
            {
                LogManager.APILog.WriteLineAndConsole("Physics Meteroid - spawnMeteor(" + spawnpos.ToString() + ", " + vel.ToString() + ", " + up.ToString() + ", " + forward.ToString() + ")" );
            }
            MyObjectBuilder_FloatingObject tempobject;
            MyObjectBuilder_Ore tempore = new MyObjectBuilder_Ore();
            MyObjectBuilder_InventoryItem tempitem = new MyObjectBuilder_InventoryItem();
            tempore.SetDefaultProperties();
            FloatingObject physicsmeteor;
            m_ore_fctr = m_gen.NextDouble();

            tempitem = (MyObjectBuilder_InventoryItem)MyObjectBuilder_InventoryItem.CreateNewObject(m_InventoryItemType);
            tempitem.PhysicalContent = (MyObjectBuilder_PhysicalObject)MyObjectBuilder_PhysicalObject.CreateNewObject(m_OreType);
            tempitem.PhysicalContent.SubtypeName = getRandomOre();
            tempitem.AmountDecimal = Math.Round((decimal)(ore_amt * getOreFctr(tempitem.PhysicalContent.SubtypeName) * m_ore_fctr));
            if (tempitem.AmountDecimal < 1) tempitem.AmountDecimal = 1;
            tempitem.ItemId = 0;

            tempobject = (MyObjectBuilder_FloatingObject)MyObjectBuilder_FloatingObject.CreateNewObject(m_FloatingObjectType);
            tempobject.Item = tempitem;

            physicsmeteor = new FloatingObject(tempobject);
            physicsmeteor.Up = up;
            physicsmeteor.Forward = forward;
            physicsmeteor.Position = spawnpos;
            physicsmeteor.LinearVelocity = vel;
            physicsmeteor.MaxLinearVelocity = 104.7F * maxVelocityFctr;
            if (SandboxGameAssemblyWrapper.IsDebugging)
            {
                LogManager.APILog.WriteLineAndConsole("Meteor entityID: " + physicsmeteor.EntityId.ToString() + " Velocity: " + vel.ToString());
            }
            SectorObjectManager.Instance.AddEntity(physicsmeteor);
            //workaround for the velocity problem.
            Thread physicsthread = new Thread(() => velocityloop(physicsmeteor, vel));
            physicsthread.Start();
        }