private void AddFood(Mineral mineral) { var quantity = base.CargoBays.CargoVolume; if (quantity.Item2 - quantity.Item1 < mineral.VolumeInCubicMeters) { // The cargo bays are too full return; } // Try to pop this out of the map if (!_map.RemoveItem(mineral, true)) { // It's already gone return; } // Convert it to cargo Cargo_Mineral cargo = new Cargo_Mineral(mineral.MineralType, mineral.Density, mineral.VolumeInCubicMeters); // Try to add this to the cargo bays - the total volume may be enough, but the mineral may be too large for any // one cargo bay if (base.CargoBays.Add(cargo)) { // Finish removing it from the real world mineral.PhysicsBody.Dispose(); this.ShouldRecalcMass_Large = true; } else { // It didn't fit, give it back to the map _map.AddItem(mineral); } }
private ChangeInstruction(Asteroid[] remove_Asteroids, Mineral[] remove_Minerals) { this.InstructionType = MapPopulationManager.InstructionType.Remove; this.Remove_Asteroids = remove_Asteroids; this.Remove_Minerals = remove_Minerals; this.Add_Position = new Point3D(); this.Add_Velocity = new Vector3D(); this.Add_AngVel = new Vector3D(); this.Asteroid = null; this.Mineral = null; }
private ChangeInstruction(Point3D add_Position, Vector3D add_Velocity, Vector3D add_AngVel, AsteroidDNA asteroid, MineralDNA mineral, Asteroid[] remove_Asteroids, Mineral[] remove_Minerals) { this.InstructionType = MapPopulationManager.InstructionType.Merge; this.Add_Position = add_Position; this.Add_Velocity = add_Velocity; this.Add_AngVel = add_AngVel; this.Asteroid = asteroid; this.Mineral = mineral; this.Remove_Asteroids = remove_Asteroids; this.Remove_Minerals = remove_Minerals; }
public void CollidedMineral(Mineral mineral) { if (mineral.MineralType == MineralType.Ruby) { // Treat this like anti food. Remove cargo/energy/fuel to compensate for the mass of this poison. If there's not enough, // then die AddPoison(mineral); } else { // The only other mineral type should be emerald, but just consider everything else as food (the converters just go by // mass anyway) AddFood(mineral); } }
private void AddPoison(Mineral mineral) { // Try to pop this out of the map if (!_map.RemoveItem(mineral, true)) { // It's already gone return; } double mass = mineral.VolumeInCubicMeters * mineral.Density; // Try to remove the equivalent mass from the cargo bay var vomit = base.CargoBays.RemoveMineral_Mass(mass); if (vomit.Item1 > 0d) { this.ShouldRecalcMass_Large = true; } if (Math1D.IsNearValue(vomit.Item1, mass)) { // There was enough in the cargo bay to balance out the poison return; } mass -= vomit.Item1; // The remaining mass needs to come out of plasma/energy/fuel // The conversion ratios are meant to be lossy when going from mass to energy/fuel/plasma. But when run the other direction, they // become overly ideal, so bump the target mass a bit to account for that mass *= 1.1d; // Plasma is least important, take from that first if (AddPoisonSprtContainer(ref mass, this.Plasma, _itemOptions.MatterToPlasma_ConversionRate)) { // There was enough to cover it return; } // Draw from fuel next if (this.Fuel != null && this.Fuel.QuantityCurrent > 0d) { this.ShouldRecalcMass_Large = true; // fuel is about to be removed, so set this now } if (AddPoisonSprtContainer(ref mass, this.Fuel, _itemOptions.MatterToFuel_ConversionRate)) { // There was enough to cover it return; } // Go after energy as a last resort if (AddPoisonSprtContainer(ref mass, this.Energy, _itemOptions.MatterToEnergy_ConversionRate)) { // There was enough to cover it return; } // If there's nothing left, then just exist. The next time this bot is examined, it will be considered dead }
public void CollidedMineral(Mineral mineral, World world, int materialID, SharedVisuals sharedVisuals) { //TODO: Let the user specify thresholds for which minerals to take ($, density, mass, type). Also give an option to be less picky if near empty //TODO: Let the user specify thresholds for swapping lesser minerals for better ones //TODO: Add a portion if (base.CargoBays == null) { return; } else if (mineral.IsDisposed) { return; } var quantity = base.CargoBays.CargoVolume; if (quantity.Item2 - quantity.Item1 < mineral.VolumeInCubicMeters) { // The cargo bays are too full return; } // Save location in case it needs to be brought back Point3D position = mineral.PositionWorld; // Convert it to cargo Cargo_Mineral cargo = new Cargo_Mineral(mineral.MineralType, mineral.Density, mineral.VolumeInCubicMeters); // Try to add this to the cargo bays - the total volume may be enough, but the mineral may be too large for any // one cargo bay (or some of the cargo bays could be destroyed) if (base.CargoBays.Add(cargo)) { // Finish removing it from the real world _map.RemoveItem(mineral, true); mineral.PhysicsBody.Dispose(); this.ShouldRecalcMass_Large = true; } }
/// <summary> /// This will take the mineral if it fits /// NOTE: This method removes the mineral from the map /// </summary> private void CollidedMineral_ORIG(Mineral mineral, World world, int materialID, SharedVisuals sharedVisuals) { //TODO: Let the user specify thresholds for which minerals to take ($, density, mass, type). Also give an option to be less picky if near empty //TODO: Let the user specify thresholds for swapping lesser minerals for better ones if (base.CargoBays == null) { return; } else if (mineral.IsDisposed) { return; } var quantity = base.CargoBays.CargoVolume; if (quantity.Item2 - quantity.Item1 < mineral.VolumeInCubicMeters) { // The cargo bays are too full return; } // Save location in case it needs to be brought back Point3D position = mineral.PositionWorld; // Try to pop this out of the map if (!_map.RemoveItem(mineral, true)) { // It's already gone return; } // Convert it to cargo Cargo_Mineral cargo = new Cargo_Mineral(mineral.MineralType, mineral.Density, mineral.VolumeInCubicMeters); // Try to add this to the cargo bays - the total volume may be enough, but the mineral may be too large for any // one cargo bay if (base.CargoBays.Add(cargo)) { // Finish removing it from the real world mineral.PhysicsBody.Dispose(); this.ShouldRecalcMass_Large = true; } else { // It didn't fit, give it back to the map Mineral clone = new Mineral(mineral.MineralType, position, mineral.VolumeInCubicMeters, world, materialID, sharedVisuals, ItemOptionsAstMin2D.MINERAL_DENSITYMULT, mineral.Scale, mineral.Credits); _map.AddItem(clone); } }
private void CreateMinerals_Build(MineralType mineralType, Point3D position) { double volume = StaticRandom.NextPercent(ItemOptionsAstMin2D.MINERAL_AVGVOLUME, 2); decimal credits = ItemOptionsAstMin2D.GetCredits_Mineral(mineralType, volume); double scale = volume / ItemOptionsAstMin2D.MINERAL_AVGVOLUME; Mineral mineral = new Mineral(mineralType, position, volume, _world, _material_Mineral, _sharedVisuals, ItemOptionsAstMin2D.MINERAL_DENSITYMULT, scale, credits); mineral.PhysicsBody.AngularVelocity = Math3D.GetRandomVector_Spherical(1d); mineral.PhysicsBody.Velocity = Math3D.GetRandomVector_Circular(6d); _map.AddItem(mineral); }
// This also creates minerals private IMapObject[] GetChildAsteroids(double overDamage, Point3D parentPos, Vector3D parentVel) { const double MAXOVERDMG = 13; // overdamage of 1 is the smallest value (the asteroid was barely destroyed). Larger values are overkill, and the asteroid becomes more fully destroyed const int MAXCHILDREN = 5; #region Child asteroid sizes // Figure out the radius of the child asteroids double radius = GetTotalChildRadius(_radius, overDamage, MAXOVERDMG); // Get the volumes of the child asteroids double[] asteroidVolumes = null; if (radius > _minChildRadius) { double totalVolume = 4d / 3d * Math.PI * radius * radius * radius; double minVolume = 4d / 3d * Math.PI * _minChildRadius * _minChildRadius * _minChildRadius; int numChildren = GetNumChildren(radius, MAXCHILDREN, totalVolume, minVolume, overDamage, MAXOVERDMG); asteroidVolumes = GetChildVolumes(numChildren, totalVolume, minVolume); } else { // Not enough left, don't create any child asteroids radius = 0; asteroidVolumes = new double[0]; } #endregion #region Mineral sizes MineralDNA[] mineralDefinitions = null; if (_getMineralsByDestroyedMass != null) { //double destroyedMass = GetDestroyedMass(Math3D.Avg(_radius.X, _radius.Y, _radius.Z), radius, _getMassByRadius); // using avg had too many cases where the returned mass was negative double destroyedMass = GetDestroyedMass(Math1D.Max(_radius.X, _radius.Y, _radius.Z), radius, _getMassByRadius); if (destroyedMass > 0) // child radius is calculated using max of _radius, but avg was passed to the getmass method. So there's a chance that getmass returns negative { mineralDefinitions = _getMineralsByDestroyedMass(destroyedMass); } } if (mineralDefinitions == null) { mineralDefinitions = new MineralDNA[0]; } #endregion if (asteroidVolumes.Length == 0 && mineralDefinitions.Length == 0) { // Nothing to spawn return null; } // Figure out positions AsteroidOrMineralDefinition[] children = PositionChildAsteroidsAndMinerals(asteroidVolumes, mineralDefinitions); #region Create IMapObjects IMapObject[] retVal = new IMapObject[children.Length]; for (int cntr = 0; cntr < retVal.Length; cntr++) { Point3D position = parentPos + children[cntr].Part.Position.ToVector(); if (children[cntr].IsAsteroid) { // Asteroid AsteroidExtra extra = new AsteroidExtra() { Triangles = children[cntr].AsteroidTriangles, GetMineralsByDestroyedMass = _getMineralsByDestroyedMass, MineralMaterialID = _mineralMaterialID, MinChildRadius = _minChildRadius, }; retVal[cntr] = new Asteroid(children[cntr].AsteroidRadius, _getMassByRadius, position, _world, _map, _materialID, extra); } else { // Mineral MineralDNA mindef = children[cntr].MineralDefinition; double densityMult = mindef.Density / Mineral.GetSettingsForMineralType(mindef.MineralType).Density; retVal[cntr] = new Mineral(mindef.MineralType, position, mindef.Volume, _world, _mineralMaterialID, _sharedVisuals.Value, densityMult, mindef.Scale); } retVal[cntr].PhysicsBody.Rotation = children[cntr].Part.Orientation; Vector3D velFromCenter = children[cntr].Part.Position.ToVector().ToUnit(false); velFromCenter *= UtilityCore.GetScaledValue(1, 4, 1, MAXOVERDMG, overDamage); retVal[cntr].PhysicsBody.Velocity = parentVel + velFromCenter; retVal[cntr].PhysicsBody.AngularVelocity = Math3D.GetRandomVector_Spherical(UtilityCore.GetScaledValue(.5, 8, 1, MAXOVERDMG, overDamage)); } #endregion return retVal; }
/// <summary> /// This will take the mineral if it fits /// NOTE: This method removes the mineral from the map /// </summary> public void CollidedMineral(Mineral mineral) { //TODO: Let the user specify thresholds for which minerals to take ($, density, mass, type). Also give an option to be less picky if near empty //TODO: Let the user specify thresholds for swapping lesser minerals for better ones var quantity = base.CargoBays.CargoVolume; if (quantity.Item2 - quantity.Item1 < mineral.VolumeInCubicMeters) { // The cargo bays are too full return; } // Try to pop this out of the map if (!_map.RemoveItem(mineral, true)) { // It's already gone return; } // Convert it to cargo Cargo_Mineral cargo = new Cargo_Mineral(mineral.MineralType, mineral.Density, mineral.VolumeInCubicMeters); // Try to add this to the cargo bays - the total volume may be enough, but the mineral may be too large for any // one cargo bay if (base.CargoBays.Add(cargo)) { // Finish removing it from the real world mineral.PhysicsBody.Dispose(); this.ShouldRecalcMass_Large = true; } else { // It didn't fit, give it back to the map _map.AddItem(mineral); } }
public ChangeInstruction(Point3D add_Position, Vector3D add_Velocity, Vector3D add_AngVel, MineralDNA mineral, Mineral[] remove_Minerals) : this(add_Position, add_Velocity, add_AngVel, null, mineral, null, remove_Minerals) { }
public ChangeInstruction(Mineral[] remove_Minerals) : this((Asteroid[])null, remove_Minerals) { }
private void AddMineral(ChangeInstruction instr) { Mineral mineral = new Mineral(instr.Mineral.MineralType, instr.Add_Position, instr.Mineral.Volume, _world, _material_Mineral, _sharedVisuals, ItemOptionsAstMin2D.MINERAL_DENSITYMULT, instr.Mineral.Volume / ItemOptionsAstMin2D.MINERAL_AVGVOLUME); mineral.PhysicsBody.AngularVelocity = instr.Add_AngVel; mineral.PhysicsBody.Velocity = instr.Add_Velocity; _map.AddItem(mineral); }
private Visual3D GetMineralBlip(Mineral mineral) { //if (mineral.Radius < 2) // limit by value instead of size //{ // // No need to flood the map with tiny minerals // return null; //} // Using the mineral's color makes the map look very busy. Instead, set an intensity of a solid color based on its relative value // in relation to the other minerals if (_mineralColors == null) { GetMineralBlipSprtCacheProps(); } MineralBlipProps blipProps = _mineralColors[mineral.MineralType]; double size = blipProps.Size * mineral.VolumeInCubicMeters; // blipProps.Size is for a volume of 1, so adjust by volume // Material MaterialGroup materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(blipProps.DiffuseColor))); materials.Children.Add(new SpecularMaterial(new SolidColorBrush(blipProps.SpecularColor), 100d)); // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; geometry.Geometry = _blipGeometry_Circle.Value; geometry.Transform = new ScaleTransform3D(size, size, size * .25d); // Model Visual ModelVisual3D retVal = new ModelVisual3D(); retVal.Content = geometry; // Exit Function return retVal; }
private void ShowEmerald_Click(object sender, RoutedEventArgs e) { try { RemoveItem_Click(this, new RoutedEventArgs()); Point3D position = new Point3D(0, 0, 0); Mineral mineral = new Mineral(MineralType.Emerald, position, 1d, _world, _material_Item, _sharedVisuals, scale: 6d); mineral.PhysicsBody.AngularVelocity = Math3D.GetRandomVector_Spherical(2d); //mineral.PhysicsBody.Velocity = Math3D.GetRandomVector_Spherical(4d); _map.AddItem(mineral); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void CreateMinerals_Build(MineralType mineralType) { Mineral mineral = new Mineral(mineralType, new Point3D(0, 0, 0), .0005d, _world, _material_Mineral, _sharedVisuals); var posVel = GetPositionVelocity(mineral.PhysicsBody.Mass); mineral.PhysicsBody.Position = posVel.Item1; mineral.PhysicsBody.AngularVelocity = Math3D.GetRandomVector_Spherical(1d); mineral.PhysicsBody.Velocity = posVel.Item2; mineral.PhysicsBody.ApplyForceAndTorque += new EventHandler<BodyApplyForceAndTorqueArgs>(Mineral_ApplyForceAndTorque); _map.AddItem(mineral); }
private void btnAddPoison_Click(object sender, RoutedEventArgs e) { try { Point3D position = Math3D.GetRandomVector_Spherical(BOUNDRYSIZEHALF * .75d).ToPoint(); Mineral mineral = new Mineral(MineralType.Ruby, position, .15d, _world, _material_Food, _sharedVisuals); mineral.PhysicsBody.AngularVelocity = Math3D.GetRandomVector_Spherical(1d); mineral.PhysicsBody.Velocity = Math3D.GetRandomVector_Spherical(4d); mineral.PhysicsBody.ApplyForceAndTorque += new EventHandler<BodyApplyForceAndTorqueArgs>(Food_ApplyForceAndTorque); _map.AddItem(mineral); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private IMapObject[] ConvertToMapObjects(AsteroidOrMineralDefinition[] items, Point3D parentPos, Vector3D parentVel, Quaternion parentRot) { IMapObject[] retVal = new IMapObject[items.Length]; RotateTransform3D rotate = new RotateTransform3D(new QuaternionRotation3D(parentRot)); for (int cntr = 0; cntr < retVal.Length; cntr++) { Point3D position = parentPos + rotate.Transform(items[cntr].Part.Position.ToVector()); if (items[cntr].IsAsteroid) { // Asteroid AsteroidExtra extra = new AsteroidExtra() { Triangles = TriangleIndexed.Clone_Transformed(items[cntr].AsteroidTriangles, rotate), GetMineralsByDestroyedMass = _getMineralsByDestroyedMass, MineralMaterialID = _mineralMaterialID, MinChildRadius = _minChildRadius, RandomRotation = false, SelfDestructAfterElapse = items[cntr].ShouldAsteroidSelfDestruct ? StaticRandom.NextPercent(SELFDESTRUCTTIME, .5) : (double?)null, MineralsWhenSelfDestruct = items[cntr].MineralsAfterSelfDestruct, }; retVal[cntr] = new Asteroid(items[cntr].AsteroidRadius, _getMassByRadius, position, _world, _map, _materialID, extra); } else { // Mineral MineralDNA mindef = items[cntr].MineralDefinition; double densityMult = mindef.Density / Mineral.GetSettingsForMineralType(mindef.MineralType).Density; retVal[cntr] = new Mineral(mindef.MineralType, position, mindef.Volume, _world, _mineralMaterialID, _sharedVisuals.Value, densityMult, mindef.Scale); } retVal[cntr].PhysicsBody.Velocity = parentVel + rotate.Transform(items[cntr].Velocity); // Need to be careful if setting this. Too much, and it will come apart unnaturally //retVal[cntr].PhysicsBody.AngularVelocity = ; } return retVal; }