public static void calcEccentricity(Dice ourDice, Star s) { int modifiers = 0; //reset the thing. if (OptionCont.lessStellarEccent) { //now we generate eccentricities if (s.orbitalSep == Star.ORBSEP_VERYCLOSE) modifiers = modifiers - 10; //Very Close if (s.orbitalSep == Star.ORBSEP_CLOSE) modifiers = modifiers - 6; //Close if (s.orbitalSep == Star.ORBSEP_MODERATE) modifiers = modifiers - 2; //Moderate } else { if (s.orbitalSep == Star.ORBSEP_VERYCLOSE) modifiers = modifiers - 6; //Very Close if (s.orbitalSep == Star.ORBSEP_CLOSE) modifiers = modifiers - 4; //Close if (s.orbitalSep == Star.ORBSEP_MODERATE) modifiers = modifiers - 2; //Moderate } int roll = ourDice.gurpsRoll(modifiers); Star.generateEccentricity(roll, s); if (OptionCont.forceVeryLowStellarEccent) { if (s.orbitalEccent > .2) s.orbitalEccent = .1; if (s.orbitalEccent > .1 && s.orbitalEccent < .2) s.orbitalEccent = .05; } }
/// <summary> /// Populates orbits around a star, according to GURPS 4e rules. (Does not create them) /// </summary> /// <param name="s">The star we're populating around</param> /// <param name="myDice">Our dice object.</param> public static void populateOrbits(Star s, Dice myDice) { double maxRatio = 2.0; double minRatio = 1.4; double minDistance = .15; bool firstGasGiant = true; if (s.containsGasGiants()) firstGasGiant = false; for (int i = 0; i < s.sysPlanets.Count; i++) { int roll = myDice.gurpsRoll(); //set gas giants first. if (s.gasGiantFlag != Star.GASGIANT_NONE) { //BEFORE SNOW LINE: Only Eccentric, Epistellar if (s.sysPlanets[i].orbitalRadius < Star.snowLine(s.initLumin)) { if (roll <= 8 && s.gasGiantFlag == Star.GASGIANT_ECCENTRIC) { s.sysPlanets[i].updateType(Satellite.BASETYPE_GASGIANT); libStarGen.updateGasGiantSize(s.sysPlanets[i],myDice.gurpsRoll() + 4); } if (roll <= 6 && s.gasGiantFlag == Star.GASGIANT_EPISTELLAR) { s.sysPlanets[i].updateType(Satellite.BASETYPE_GASGIANT); libStarGen.updateGasGiantSize(s.sysPlanets[i], myDice.gurpsRoll() + 4); } } //AFTER SNOW LINE: All three if (s.sysPlanets[i].orbitalRadius >= Star.snowLine(s.initLumin)) { if (roll <= 15 && s.gasGiantFlag == Star.GASGIANT_CONVENTIONAL) { s.sysPlanets[i].updateType(Satellite.BASETYPE_GASGIANT); if (firstGasGiant) { libStarGen.updateGasGiantSize(s.sysPlanets[i], myDice.gurpsRoll() + 4); firstGasGiant = false; } else libStarGen.updateGasGiantSize(s.sysPlanets[i], myDice.gurpsRoll()); } if (roll <= 14 && (s.gasGiantFlag == Star.GASGIANT_ECCENTRIC || s.gasGiantFlag == Star.GASGIANT_EPISTELLAR)) { s.sysPlanets[i].updateType(Satellite.BASETYPE_GASGIANT); if (firstGasGiant) { libStarGen.updateGasGiantSize(s.sysPlanets[i], myDice.gurpsRoll() + 4); firstGasGiant = false; } else libStarGen.updateGasGiantSize(s.sysPlanets[i], myDice.gurpsRoll()); } } } //Done with the gas giant. Let's go start seeign what else it could be. //We can get mods now. if (s.sysPlanets[i].baseType != Satellite.BASETYPE_GASGIANT) { //INNER AND OUTER RADIUS int mod = 0; if (s.sysPlanets[i].orbitalRadius - minDistance <= Star.innerRadius(s.initLumin,s.initMass) || s.sysPlanets[i].orbitalRadius / Star.innerRadius(s.initLumin, s.initMass) <= maxRatio) { mod = mod - 3; } if (s.sysPlanets[i].orbitalRadius + minDistance >= Star.outerRadius(s.initMass) || Star.outerRadius(s.initMass) / s.sysPlanets[i].orbitalRadius <= maxRatio) { mod = mod - 3; } //FORBIDDDEN ZONE if (s.getClosestDistToForbiddenZone(s.sysPlanets[i].orbitalRadius) <= minDistance || (s.getClosestForbiddenZoneRatio(s.sysPlanets[i].orbitalRadius) < maxRatio && s.getClosestForbiddenZoneRatio(s.sysPlanets[i].orbitalRadius) > minRatio)) { //MessageBox.Show("THE FORBIDDEN ZONE!!!!"); mod = mod - 6; } //GAS GIANT LOCATION if (s.isPrevSatelliteGasGiant(s.sysPlanets[i].orbitalRadius)) { mod = mod - 6; } if (s.isNextSatelliteGasGiant(s.sysPlanets[i].orbitalRadius)) { mod = mod - 3; } //now let's get the orbit type. // MessageBox.Show("Mod is " + mod); mod = mod + myDice.gurpsRoll(); //MessageBox.Show("Mod + Roll is " + mod); if (mod <= 3) s.sysPlanets[i].updateType(Satellite.BASETYPE_EMPTY); if (mod >= 4 && mod <= 6) { s.sysPlanets[i].updateType(Satellite.BASETYPE_ASTEROIDBELT); //Expanded Asteroid Belt options if (OptionCont.expandAsteroidBelt) { roll = myDice.gurpsRoll(); if (roll <= 6) s.sysPlanets[i].updateSize(Satellite.SIZE_TINY); if (roll >= 7 && roll <= 13) s.sysPlanets[i].updateSize(Satellite.SIZE_SMALL); if (roll >= 14 && roll <= 15) s.sysPlanets[i].updateSize(Satellite.SIZE_MEDIUM); if (roll >= 16) s.sysPlanets[i].updateSize(Satellite.SIZE_LARGE); } else s.sysPlanets[i].updateSize(Satellite.SIZE_SMALL); //fixes a recursion bug. } if (mod >= 7 && mod <= 8) s.sysPlanets[i].updateTypeSize(Satellite.BASETYPE_TERRESTIAL, Satellite.SIZE_TINY); if (mod >= 9 && mod <= 11) s.sysPlanets[i].updateTypeSize(Satellite.BASETYPE_TERRESTIAL, Satellite.SIZE_SMALL); if (mod >= 12 && mod <= 15) s.sysPlanets[i].updateTypeSize(Satellite.BASETYPE_TERRESTIAL, Satellite.SIZE_MEDIUM); if (mod >= 16) s.sysPlanets[i].updateTypeSize(Satellite.BASETYPE_TERRESTIAL, Satellite.SIZE_LARGE); } } }
/// <summary> /// This function fills in the details of the star. /// </summary> /// <param name="s">The star to be filled in</param> /// <param name="ourDice">The dice object used</param> /// <param name="maxMass">Max mass of the system</param> /// <param name="sysName">The name of the system</param> public static void generateAStar(Star s, Dice ourDice, double maxMass, string sysName) { //check mass first - if unset, set it. if (s.currMass == 0) { if (s.orderID == Star.IS_PRIMARY) { s.updateMass(libStarGen.rollStellarMass(ourDice, s.orderID)); maxMass = s.currMass; } else s.updateMass(libStarGen.rollStellarMass(ourDice, s.orderID, maxMass)); } //if we are in the white dwarf branch, reroll mass. if (s.evoLine.findCurrentAgeGroup(s.starAge) == StarAgeLine.RET_COLLASPEDSTAR) s.updateMass(ourDice.rollInRange(0.9, 1.4),true); //set the generic name s.name = Star.genGenericName(sysName, s.orderID); //initalize the luminosity first, then update it given the current age, status and mass. s.setLumin(); s.currLumin = Star.getCurrLumin(s.evoLine, s.starAge, s.currMass); //determine the temperature s.effTemp = Star.getInitTemp(s.currMass); s.effTemp = Star.getCurrentTemp(s.evoLine, s.currLumin, s.starAge, s.currMass, ourDice); //DERIVED STATS: RADIUS, Spectral Type s.radius = Star.getRadius(s.currMass, s.effTemp, s.currLumin, s.evoLine.findCurrentAgeGroup(s.starAge)); s.setSpectralType(); s.starColor = Star.setColor(ourDice, s.effTemp); //set flare status. libStarGen.setFlareStatus(s, ourDice); //end this here. We will hand orbital mechanics elsewhere. }
/// <summary> /// This picks the gas giant flag for a star. /// </summary> /// <param name="myStar">The star we're setting for</param> /// <param name="roll">The dice roll</param> public static void gasGiantFlag(Star myStar, int roll) { //base set. int noGasGiant = 0; int conGaGiant = 0; int eccGaGiant = 0; int epiGaGiant = 0; if (!OptionCont.moreConGasGiantChances) { noGasGiant = 10; conGaGiant = 12; eccGaGiant = 14; epiGaGiant = 18; } else { noGasGiant = 6; conGaGiant = 13; eccGaGiant = 15; epiGaGiant = 18; } if (roll <= noGasGiant) myStar.gasGiantFlag = Star.GASGIANT_NONE; if (roll > noGasGiant && roll <= conGaGiant) myStar.gasGiantFlag = Star.GASGIANT_CONVENTIONAL; if (roll > conGaGiant && roll <= eccGaGiant) myStar.gasGiantFlag = Star.GASGIANT_ECCENTRIC; if (roll > eccGaGiant && roll <= epiGaGiant) myStar.gasGiantFlag = Star.GASGIANT_EPISTELLAR; }
/// <summary> /// This sets the flare status of a star /// </summary> /// <param name="s">The star we're setting for</param> /// <param name="ourDice">The dice object we use.</param> public static void setFlareStatus(Star s, Dice ourDice) { int roll = ourDice.gurpsRoll(); int limit = 12; double massLimit = .45; if (OptionCont.anyStarFlareStar) massLimit = 11; if (OptionCont.moreFlareStarChance) limit = 9; if (roll >= limit && s.currMass <= massLimit) s.isFlareStar = true; }
/// <summary> /// Update the display based on a mass update /// </summary> /// <param name="sender">The object sending you here</param> /// <param name="e">Event arguments</param> private void numCurrMass_Leave(object sender, EventArgs e) { //first, initial luminosity txtInitLumin.Text = Star.getMinLumin((double)numCurrMass.Value).ToString(); //now we need to get an updated timeline this.currAgeChart.addMainLimit(Star.findMainLimit((double)numCurrMass.Value)); this.currAgeChart.addSubLimit(Star.findSubLimit((double)numCurrMass.Value)); this.currAgeChart.addGiantLimit(Star.findGiantLimit((double)numCurrMass.Value)); //now we need to get what stage we are and push the details to the field. lblEndMain.Text = "End of Main Sequence: " + this.currAgeChart.getMainLimit() + " GYr"; lblEndSubGiant.Text = "End of the Sub Giant Sequence: " + this.currAgeChart.getSubLimit() + " GYr"; lblEndGiantPhase.Text = "End of the Giant Phase: " + this.currAgeChart.getGiantLimit() + " GYr"; this.currAgeStatus = this.currAgeChart.findCurrentAgeGroup((double)numAge.Value); lblCurrentStage.Text = "Current Status: " + StarAgeLine.descBranch(this.currAgeStatus); //now we can get the current luminosity, figure out what the intial mass is. //and fill in the effective temperature if it's no longer in range. numInitMass.Value = numCurrMass.Value; txtCurrLumin.Text = Math.Round(Star.getCurrLumin(this.currAgeChart, (double)numAge.Value, (double)numCurrMass.Value), 3).ToString(); double temp; temp = Star.getCurrentTemp(this.currAgeChart, Convert.ToDouble(txtCurrLumin.Text), (double)numAge.Value, (double)numCurrMass.Value, this.myDice); txtEffTemp.Text = Convert.ToString(temp); //set good ranges createAcceptRanges(Star.getCurrLumin(this.currAgeChart, (double)numAge.Value, (double)numCurrMass.Value), temp); //display information for users benefits (formation zones, colors) this.color = Star.setColor(this.myDice, temp); lblStellarColor.Text = "Stellar Color: " + color; lblStellarRadius.Text = "Stellar Radius: " + Star.getRadius((double)numCurrMass.Value, temp, Star.getCurrLumin(this.currAgeChart, (double)numAge.Value, (double)numCurrMass.Value), this.currAgeChart.findCurrentAgeGroup((double)numAge.Value)) + " AU"; lblInnerFormation.Text = "Inner Formation Range: " + Star.innerRadius(Convert.ToDouble(txtInitLumin.Text), (double)numInitMass.Value) + " AU"; lblOuterFormation.Text = "Outer Formation Range: " + Star.outerRadius((double)numInitMass.Value) + " AU"; lblSnowLine.Text = "Snow Line: " + Star.snowLine(Convert.ToDouble(txtInitLumin.Text)) + " AU"; if ((double)numCurrMass.Value > .525) { chkFlareStar.Checked = false; chkFlareStar.Enabled = false; } }
public void addStar(Star newStar) { this.sysStars.Add(newStar); }
public virtual Range getConventionalRange() { return(new Range(Star.snowLine(this.initLumin), 1.5 * Star.snowLine(this.initLumin))); }
public virtual Range getEccentricRange() { return(new Range(.125 * Star.snowLine(this.initLumin), .75 * Star.snowLine(this.initLumin))); }
public virtual Range getEpistellarRange() { return(new Range(.1 * Star.innerRadius(this.initLumin, this.initMass), 1.8 * Star.innerRadius(this.initLumin, this.initMass))); }
public virtual Range generateFormationRange() { return(new Range(Star.innerRadius(this.initLumin, this.initMass), Star.outerRadius(this.initMass))); }
public override String ToString() { String ret = "This forbidden zone is from " + this.lowerBound + " to " + this.upperBound + " AU"; ret = ret + Environment.NewLine + " " + "From star " + Star.getDescSelfFlag(this.primaryStar) + " to " + Star.getDescSelfFlag(this.secondaryStar); return(ret); }