private void CreateThrusters(ThrusterDNA[] thrustDNA) { if (_thrusters != null) { throw new InvalidOperationException("Existing thrusters should have been wiped out before calling CreateThrusters"); } _thrusters = new ThrusterStuff[thrustDNA.Length]; // Thrusters for (int cntr = 0; cntr < thrustDNA.Length; cntr++) { _thrusters[cntr] = new ThrusterStuff(); _thrusters[cntr].Thrust = new Thruster(_editorOptions, _itemOptions, thrustDNA[cntr], _containers == null ? null : _containers.Fuel); _thrusters[cntr].DNAExternalLinks = thrustDNA[cntr].ExternalLinks; } #region Ship Visuals foreach (var thrust in _thrusters) { // WPF ModelVisual3D model = new ModelVisual3D(); model.Content = thrust.Thrust.Model; //TODO: Offset this if there are multiple parts _viewport.Children.Add(model); thrust.Visual = model; // Physics using (CollisionHull hull = thrust.Thrust.CreateCollisionHull(_world)) { thrust.Body = new Body(hull, Matrix3D.Identity, thrust.Thrust.TotalMass, new Visual3D[] { model }); thrust.Body.MaterialGroupID = _material_Ship; thrust.Body.LinearDamping = .01f; thrust.Body.AngularDamping = new Vector3D(.01f, .01f, .01f); } } #endregion #region Neuron Visuals foreach (var thrust in _thrusters) { ModelVisual3D model; BuildNeuronVisuals(out thrust.Neurons, out model, thrust.Thrust.Neruons_All, thrust.Thrust, _colors); thrust.NeuronVisual = model; _viewportNeural.Children.Add(model); } #endregion UpdateCountReport(); }
private PartBase GetRandomPart() { Point3D position = Math3D.GetRandomVector(2d).ToPoint(); Quaternion orientation = Math3D.GetRandomRotation(); double radius = 1d + StaticRandom.NextDouble() * 4d; double height = 1d + StaticRandom.NextDouble() * 4d; switch (StaticRandom.Next(8)) { case 0: #region Spin double spinSize = 5d + (StaticRandom.NextDouble() * 8d); ShipPartDNA dnaSpin = new ShipPartDNA() { PartType = SensorSpin.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(spinSize, spinSize, spinSize) }; return new SensorSpin(_editorOptions, _itemOptions, dnaSpin, null); #endregion case 1: #region Fuel ShipPartDNA dnaFuel = new ShipPartDNA() { PartType = FuelTank.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, height) }; FuelTank fuel = new FuelTank(_editorOptions, _itemOptions, dnaFuel); fuel.QuantityCurrent = fuel.QuantityMax; // without this, the fuel tank gets tossed around because it's so light return fuel; #endregion case 2: #region Energy ShipPartDNA dnaEnergy = new ShipPartDNA() { PartType = EnergyTank.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, height) }; return new EnergyTank(_editorOptions, _itemOptions, dnaEnergy); #endregion case 3: #region Brain ShipPartDNA dnaBrain = new ShipPartDNA() { PartType = Brain.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, radius) }; return new Brain(_editorOptions, _itemOptions, dnaBrain, null); #endregion case 4: #region Thruster ThrusterDNA dnaThruster1 = new ThrusterDNA() { PartType = Thruster.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(height, height, height), ThrusterType = UtilityCore.GetRandomEnum(ThrusterType.Custom) }; return new Thruster(_editorOptions, _itemOptions, dnaThruster1, null); #endregion case 5: #region Solar ConverterRadiationToEnergyDNA dnaSolar = new ConverterRadiationToEnergyDNA() { PartType = ConverterRadiationToEnergy.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(height, 1d + StaticRandom.NextDouble() * 4d, 1d), Shape = UtilityCore.GetRandomEnum<SolarPanelShape>() }; return new ConverterRadiationToEnergy(_editorOptions, _itemOptions, dnaSolar, null, _radiation); #endregion case 6: #region Fuel->Energy ShipPartDNA dnaBurner = new ShipPartDNA() { PartType = ConverterFuelToEnergy.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, height) }; return new ConverterFuelToEnergy(_editorOptions, _itemOptions, dnaBurner, null, null); #endregion case 7: #region Energy->Ammo ShipPartDNA dnaReplicator = new ShipPartDNA() { PartType = ConverterEnergyToAmmo.PARTTYPE, Position = position, Orientation = orientation, Scale = new Vector3D(radius, radius, height) }; return new ConverterEnergyToAmmo(_editorOptions, _itemOptions, dnaReplicator, null, null); #endregion default: throw new ApplicationException("Unexpected integer"); } }
private void btnThrusters_Click(object sender, RoutedEventArgs e) { try { int numThrusters; if (!int.TryParse(txtThrusterCount.Text, out numThrusters)) { MessageBox.Show("Couldn't parse number of thrusters", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } if (numThrusters < 1) { MessageBox.Show("The number of thrusters must be greater than zero", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } // Wipe Existing ClearThrusters(); if (_containers == null) { CreateContainers(); } // Build DNA ThrusterDNA dna = new ThrusterDNA(); dna.PartType = Thruster.PARTTYPE; dna.Position = new Point3D(2, 0, 0); dna.Orientation = new Quaternion(new Vector3D(0, 1, 0), -90); dna.Scale = new Vector3D(.5, .5, .5); dna.ThrusterType = ThrusterType.One; //dna.ThrusterType = ThrusterType.Custom; dna.ThrusterDirections = ThrusterDesign.GetThrusterDirections(ThrusterType.One); ThrusterDNA[] dnaThrust = new ThrusterDNA[numThrusters]; for (int cntr = 0; cntr < numThrusters; cntr++) { if (numThrusters == 1) { dnaThrust[cntr] = dna; } else { ThrusterDNA dnaCopy = (ThrusterDNA)ShipPartDNA.Clone(dna); double angle = 360d / Convert.ToDouble(numThrusters); dnaCopy.Position += new Vector3D(0, .75, 0).GetRotatedVector(new Vector3D(1, 0, 0), angle * cntr); dnaThrust[cntr] = dnaCopy; } } // Create/Show fuel,thrusters CreateThrusters(dnaThrust); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
public Thruster(EditorOptions options, ItemOptions itemOptions, ThrusterDNA dna, IContainer fuelTanks) : base(options, dna, itemOptions.Thruster_Damage.HitpointMin, itemOptions.Thruster_Damage.HitpointSlope, itemOptions.Thruster_Damage.Damage) { _itemOptions = itemOptions; _fuelTanks = fuelTanks; if (dna.ThrusterType == ThrusterType.Custom) { this.Design = new ThrusterDesign(options, true, dna.ThrusterDirections); } else { this.Design = new ThrusterDesign(options, true, dna.ThrusterType); } this.Design.SetDNA(dna); double radius; double cylinderVolume = GetVolume(out radius, out _scaleActual, dna); this.Radius = radius; Vector3D[] thrustDirections = ((ThrusterDesign)this.Design).ThrusterDirections; _mass = GetMass(itemOptions, thrustDirections.Length, cylinderVolume); _forceAtMax = cylinderVolume * itemOptions.Thruster_StrengthRatio * ItemOptions.FORCESTRENGTHMULT; //ThrusterStrengthRatio is stored as a lower value so that the user doesn't see such a huge number RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(dna.Orientation)); this.ThrusterDirectionsShip = thrustDirections.Select(o => transform.Transform(o)).ToArray(); //NOTE: It is expected that Design.ThrusterDirections are unit vectors _neurons = CreateNeurons(thrustDirections); }
public override ShipPartDNA GetDNA() { ThrusterDNA retVal = new ThrusterDNA(); base.FillDNA(retVal); retVal.ThrusterType = this.ThrusterType; retVal.ThrusterDirections = this.ThrusterDirections; return retVal; }
private static double GetVolume(out double radius, out Vector3D actualScale, ThrusterDNA dna) { // Just assume it's a cylinder double radX = dna.Scale.X * ThrusterDesign.RADIUSPERCENTOFSCALE; double radY = dna.Scale.Y * ThrusterDesign.RADIUSPERCENTOFSCALE; double height = dna.Scale.Z; radius = (radX + radY + (height * .5d)) / 3d; // this is just an approximation for the neural container actualScale = new Vector3D(radX * 2d, radY * 2d, height); return Math.PI * radX * radY * height; }
private void btnStandaloneThruster_Click(object sender, RoutedEventArgs e) { try { ThrusterDNA dna = new ThrusterDNA() { PartType = Thruster.PARTTYPE, ThrusterType = UtilityCore.GetRandomEnum<ThrusterType>(ThrusterType.Custom), Position = new Point3D(0, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(1, 1, 1) }; ModifyDNA(dna, chkStandaloneRandSize.IsChecked.Value, chkStandaloneRandOrientation.IsChecked.Value); double size = (dna.Scale.X + dna.Scale.Y + dna.Scale.Z) / 3d; dna.Scale = new Vector3D(size, size, size); Thruster thruster = new Thruster(_editorOptions, _itemOptions, dna, null); BuildStandalonePart(thruster); if (chkStandaloneShowMassBreakdown.IsChecked.Value) { double cellSize = Math1D.Max(dna.Scale.X, dna.Scale.Y, dna.Scale.Z) * UtilityCore.GetScaledValue_Capped(.1d, .3d, 0d, 1d, _rand.NextDouble()); DrawMassBreakdown(thruster.GetMassBreakdown(cellSize), cellSize); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void btnThruster_Click(object sender, RoutedEventArgs e) { try { ShipPartDNA dna = GetDefaultDNA(FuelTank.PARTTYPE); FuelTank fuelTank = new FuelTank(_editorOptions, _itemOptions, dna); ThrusterDNA dna2 = new ThrusterDNA() { PartType = Thruster.PARTTYPE, ThrusterType = UtilityCore.GetRandomEnum<ThrusterType>(), Position = new Point3D(0, 0, 0), Orientation = Quaternion.Identity, Scale = new Vector3D(1, 1, 1) }; Thruster thruster = new Thruster(_editorOptions, _itemOptions, dna2, fuelTank); fuelTank.QuantityCurrent = fuelTank.QuantityMax; double percent; Vector3D? thrust; do { percent = 1d; thrust = thruster.Fire(ref percent, 0, 1d); } while (fuelTank.QuantityCurrent > 0d); percent = 1d; thrust = thruster.Fire(ref percent, 0, 1d); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }