Merge pull request #20 from Krafpy/converter-stock-combine

Combine with stock checkbox
This commit is contained in:
Krafpy
2022-08-20 15:09:29 +02:00
committed by GitHub
7 changed files with 190 additions and 40 deletions

View File

@@ -7,8 +7,8 @@
# mass: kg
# stdGravParam: m^3/s^2
# soi: m
# apoapsis: m
# periapsis: m
# apoapsis: m - optional
# periapsis: m - optional
# eccentricity: None
# inclination: ° (degrees)
# argOfPeriapsis: °
@@ -19,6 +19,10 @@
# EDIT NOTES FOR CUSTOM SOLAR SYSTEMS
# If your solar system uses Kopernicus' configuration files, you can directly convert them
# into a `bodies.yml` file on this page : https://krafpy.github.io/KSP-MGA-Planner/tools/cfg-to-yml/
# For custom solar systems, the following rules apply to all `bodies.yml`:
# - Follow the exact same format (names, indentations) as used in this file
# - Numerical data must follow the units described above
# - Each body has a unique ID, it must be an integer between 0 and N-1, where N is the number of bodies

View File

@@ -58,6 +58,25 @@ export function parseToBodyConfig(bodyConfig, templateBodies) {
},
};
}
export function completeBodytoUnorderedData(body) {
return {
name: body.name,
radius: body.radius,
mass: body.mass,
stdGravParam: body.stdGravParam,
soi: body.soi,
orbit: {
semiMajorAxis: body.orbit.semiMajorAxis,
eccentricity: body.orbit.eccentricity,
inclination: body.orbit.inclination,
argOfPeriapsis: body.orbit.argOfPeriapsis,
ascNodeLongitude: body.orbit.ascNodeLongitude,
},
meanAnomaly0: body.meanAnomaly0,
epoch: body.epoch,
color: body.color,
};
}
function deduceStdGravParamAndMass(bodyConfig, radius, template) {
let stdGravParam = 0, mass = 0;
if (bodyConfig.Properties.gravParameter !== undefined) {

View File

@@ -1,5 +1,5 @@
import { loadBodiesData } from "../../main/utilities/data.js";
import { orderOrbitingBodies, parseToBodyConfig, parseToSunConfig, recomputeSOIs } from "./body-data.js";
import { completeBodytoUnorderedData, orderOrbitingBodies, parseToBodyConfig, parseToSunConfig, recomputeSOIs } from "./body-data.js";
import { parseConfigNodes } from "./cfg-parser.js";
import { dumpBodyToYaml, dumpSunToYaml, joinYamlBlocks } from "./dump.js";
import { readFilesFromInput } from "./file-reader.js";
@@ -16,6 +16,7 @@ async function main() {
const convertBtn = document.getElementById("convert-btn");
const downloadBtn = document.getElementById("download-btn");
const filesInput = document.getElementById("files-input");
const combineChkBox = document.getElementById("combine-checkbox");
const convert = async () => {
var _a;
if (!((_a = filesInput.files) === null || _a === void 0 ? void 0 : _a.length))
@@ -30,12 +31,18 @@ async function main() {
configs.push(parseConfigNodes(content));
}
const sunConfig = configs.find(c => { var _a; return ((_a = c.Orbit) === null || _a === void 0 ? void 0 : _a.referenceBody) === undefined; });
if (sunConfig === undefined) {
throw new Error("Sun configuration not found.");
let sun;
if (sunConfig !== undefined) {
const unorderedSun = parseToSunConfig(sunConfig, template);
sun = { id: 0, ...unorderedSun };
}
else {
if (!combineChkBox.checked) {
throw new Error("Sun configuration not found.");
}
TextareaLogger.log("Using stock Sun");
sun = template.get("Sun");
}
const unorderedSun = parseToSunConfig(sunConfig, template);
const sun = { id: 0, ...unorderedSun };
TextareaLogger.log(`Ordering...`);
const orbitingUnordered = [];
for (const config of configs) {
if (config.Orbit) {
@@ -43,6 +50,10 @@ async function main() {
orbitingUnordered.push(orbiting);
}
}
if (combineChkBox.checked) {
completeWithStock(orbitingUnordered, stockBodies.bodies, sun.name);
}
TextareaLogger.log(`Ordering...`);
const orbiting = orderOrbitingBodies(orbitingUnordered, sun.name);
TextareaLogger.log("Recomputing SOIs...");
recomputeSOIs(orbiting, sun);
@@ -50,14 +61,34 @@ async function main() {
const sunYml = dumpSunToYaml(sun);
const orbitingYml = orbiting.map(body => dumpBodyToYaml(body));
const yml = joinYamlBlocks([sunYml, ...orbitingYml]);
TextareaLogger.log(`\nSuccessfully converted solar system data.`);
downloadBtn.onclick = () => download("bodies.yml", yml);
TextareaLogger.log(`\nSuccessfully converted solar system data.`);
TextareaLogger.log(`Click to download \`bodies.yml\``);
};
convertBtn.onclick = () => {
convert().catch(reason => TextareaLogger.error(reason));
};
}
function completeWithStock(unorderedOrbiting, stockOrbiting, sunName) {
const definedOrbiting = new Set();
for (const { data } of unorderedOrbiting) {
definedOrbiting.add(data.name);
}
for (const body of stockOrbiting) {
if (definedOrbiting.has(body.name))
continue;
TextareaLogger.log(`Using stock ${body.name}`);
let referenceBody = sunName;
if (body.orbiting != 0) {
const idx = body.orbiting - 1;
referenceBody = stockOrbiting[idx].name;
}
unorderedOrbiting.push({
referenceBody,
data: completeBodytoUnorderedData(body)
});
}
}
function download(filename, text) {
const element = document.createElement('a');
const encoded = encodeURIComponent(text);

View File

@@ -76,6 +76,27 @@ export function parseToBodyConfig(bodyConfig: any, templateBodies: Map<string, I
};
}
export function completeBodytoUnorderedData(body: IOrbitingBody): IOrbitingBody_Unordered {
return {
name: body.name,
radius: body.radius,
mass: body.mass,
stdGravParam: body.stdGravParam,
soi: body.soi,
orbit:
{
semiMajorAxis: body.orbit.semiMajorAxis,
eccentricity: body.orbit.eccentricity,
inclination: body.orbit.inclination,
argOfPeriapsis: body.orbit.argOfPeriapsis,
ascNodeLongitude: body.orbit.ascNodeLongitude,
},
meanAnomaly0: body.meanAnomaly0,
epoch: body.epoch,
color: body.color,
};
}
function deduceStdGravParamAndMass(bodyConfig: any, radius: number, template?: ICelestialBody){
let stdGravParam = 0, mass = 0;
@@ -93,7 +114,6 @@ function deduceStdGravParamAndMass(bodyConfig: any, radius: number, template?: I
} else {
stdGravParam = template?.stdGravParam as number;
}
return {stdGravParam, mass: mass != 0 ? mass : stdGravParam / GRAVITY_CONSTANT};
}

View File

@@ -1,5 +1,5 @@
import { loadBodiesData } from "../../main/utilities/data.js";
import { orderOrbitingBodies, parseToBodyConfig, parseToSunConfig, recomputeSOIs } from "./body-data.js";
import { completeBodytoUnorderedData, orderOrbitingBodies, parseToBodyConfig, parseToSunConfig, recomputeSOIs } from "./body-data.js";
import { parseConfigNodes } from "./cfg-parser.js";
import { dumpBodyToYaml, dumpSunToYaml, joinYamlBlocks } from "./dump.js";
import { readFilesFromInput } from "./file-reader.js";
@@ -20,6 +20,7 @@ async function main(){
const convertBtn = document.getElementById("convert-btn") as HTMLButtonElement;
const downloadBtn = document.getElementById("download-btn") as HTMLButtonElement;
const filesInput = document.getElementById("files-input") as HTMLInputElement;
const combineChkBox = document.getElementById("combine-checkbox") as HTMLInputElement;
const convert = async () => {
if(!filesInput.files?.length) return;
@@ -39,13 +40,17 @@ async function main(){
// extract ICelestiaBody data for the sun
const sunConfig = configs.find(c => c.Orbit?.referenceBody === undefined);
if(sunConfig === undefined){
throw new Error("Sun configuration not found.");
let sun: ICelestialBody;
if(sunConfig !== undefined){
const unorderedSun = parseToSunConfig(sunConfig, template);
sun = {id: 0, ...unorderedSun};
} else {
if(!combineChkBox.checked){
throw new Error("Sun configuration not found.");
}
TextareaLogger.log("Using stock Sun");
sun = template.get("Sun") as ICelestialBody;
}
const unorderedSun = parseToSunConfig(sunConfig, template);
const sun: ICelestialBody = {id: 0, ...unorderedSun};
TextareaLogger.log(`Ordering...`);
// extract IOribitingBody_Unordered (without id and orbiting)
// data for other bodies
@@ -57,6 +62,14 @@ async function main(){
}
}
// Combine with stock bodies, only add ones that have not been redefined
// in a cfg file
if(combineChkBox.checked){
completeWithStock(orbitingUnordered, stockBodies.bodies, sun.name);
}
TextareaLogger.log(`Ordering...`);
// Compute bodies's ids and sort them in the correct order
const orbiting = orderOrbitingBodies(orbitingUnordered, sun.name);
@@ -71,10 +84,9 @@ async function main(){
const orbitingYml = orbiting.map(body => dumpBodyToYaml(body));
const yml = joinYamlBlocks([sunYml, ...orbitingYml]);
TextareaLogger.log(`\nSuccessfully converted solar system data.`);
downloadBtn.onclick = () => download("bodies.yml", yml);
TextareaLogger.log(`\nSuccessfully converted solar system data.`);
TextareaLogger.log(`Click to download \`bodies.yml\``);
};
@@ -83,14 +95,37 @@ async function main(){
};
}
function completeWithStock(unorderedOrbiting: ParsedUnorderedOrbitingData[], stockOrbiting: IOrbitingBody[], sunName: string){
const definedOrbiting = new Set<string>();
for(const {data} of unorderedOrbiting) {
definedOrbiting.add(data.name);
}
for(const body of stockOrbiting){
if(definedOrbiting.has(body.name)) continue;
TextareaLogger.log(`Using stock ${body.name}`);
let referenceBody = sunName;
if(body.orbiting != 0){
const idx = body.orbiting - 1;
referenceBody = stockOrbiting[idx].name;
}
unorderedOrbiting.push({
referenceBody,
data: completeBodytoUnorderedData(body)
});
}
}
function download(filename: string, text: string) {
const element = document.createElement('a');
const encoded = encodeURIComponent(text);
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encoded);
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
}

View File

@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="shortcut icon" href="#">
<link rel="stylesheet" type="text/css" href="./../../style.css">
<!--<link rel="stylesheet" type="text/css" href="./../../style.css">-->
<link rel="stylesheet" type="text/css" href="style.css">
<title>CFG converter for MGA Planner</title>
</head>
@@ -15,21 +15,30 @@
<h2>Kopernicus .CFG converter for <a href="https://krafpy.github.io/KSP-MGA-Planner/">KSP MGA Planner</a></h2>
<p>
Use this page to quickly convert Kopernicus' configuration files (.cfg) of solar systems to the `bodies.yml`
file used by the MGA planner tool.
file used by MGA planner.
</p>
<p>
Select all .cfg files describing the solar system's bodies <em>only</em>, including the sun.
Select all .cfg files describing the solar system's bodies <em>only</em>.
Check the "Combine with stock" checkbox if the solar system is an extension to the stock one: missing configuration
files for stock bodies will be added automatically.
<p>
Follow then <strong><a href="https://github.com/Krafpy/KSP-MGA-Planner#solar-systems-support">these steps</a></strong> to
add the new solar system to the tool by contributing to the repository.
Follow then <strong><a href="https://github.com/Krafpy/KSP-MGA-Planner#solar-systems-support">these steps</a></strong>
to add the new solar system to the tool by contributing to the repository.
</p>
<div id="inputs">
<input id="files-input" type="file" multiple>
<div id="btns-div">
<div id="controls">
<div id="inputs">
<input id="files-input" type="file" multiple>
<div id="checkbox-container">
<input id="combine-checkbox" name="combine-checkbox" type="checkbox">
<label for="combine-checkbox">Combine with stock</label>
</div>
</div>
<div id="buttons">
<button id="convert-btn">Convert</button>
<button id="download-btn">Download</button>
</div>
</div>
<textarea name="log-box" id="log-box" rows="7" readonly></textarea>
</section>
</div>

View File

@@ -1,21 +1,58 @@
body
{
font-family: "Helvetica Neue", Helvetica;
/*background-color: #222425;*/
background: #1c1e1f;
color: rgb(200, 195, 188);
display: flex;
align-items: center;
}
p
{
font-size: 0.8em;
}
a:link
{
color: rgb(86, 169, 224);
text-decoration: none;
}
a:hover
{
color: rgb(116, 190, 240);
}
#container
{
display: inline-block;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
width: 570px;
}
#inputs
#controls
{
display: flex;
align-items: center;
align-items: flex-end;
justify-content: space-between;
}
#files-input
{
margin-top: 30px;
margin-bottom: 30px;
}
#combine-checkbox
{
margin-top: 20px;
}
#checkbox-container label
{
font-size: 0.8em;
}
#log-box
{
width: 100%;
@@ -38,9 +75,4 @@
button
{
width: 6em;
}
/*p, button, input
{
font-size: 0.85em;
}*/
}