Skip to content

Commit

Permalink
Added images, item browser
Browse files Browse the repository at this point in the history
  • Loading branch information
greeny committed Feb 15, 2020
1 parent 739a7fc commit c98a3e8
Show file tree
Hide file tree
Showing 396 changed files with 8,177 additions and 1,366 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ data/Docs.json

# Node stuff
node_modules
yarn-error.log

# Generated sources
www/assets/app.js
12 changes: 12 additions & 0 deletions bin/images.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as fs from 'fs';
import * as path from 'path';
const sharp = require('sharp');

const dir = path.join('www', 'assets', 'images', 'items');

for (const entry of fs.readdirSync(dir, {withFileTypes: true})) {
if (entry.isFile()) {
sharp(path.join(dir, entry.name)).resize(256, 256).toFile(path.join(dir, entry.name.replace('.png', '_256.png')));
sharp(path.join(dir, entry.name)).resize(64, 64).toFile(path.join(dir, entry.name.replace('.png', '_64.png')));
}
}
145 changes: 112 additions & 33 deletions bin/parseDocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,70 @@ import parseBuildings from '@bin/parseDocs/building';
import parseResourceExtractors from '@bin/parseDocs/resourceExtractor';
import parseGenerators from '@bin/parseDocs/generator';
import parseBuildingDescriptors from '@bin/parseDocs/buildingDescriptor';
import parseSchematics from '@bin/parseDocs/schematic';

const docs = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'data', 'Docs.json')).toString());

const json: IJsonSchema = {
recipes: [],
items: [],
generators: [],
resources: [],
miners: [],
buildings: [],
recipes: {},
items: {},
schematics: {},
generators: {},
resources: {},
miners: {},
buildings: {},
};

let biomass: IItemSchema[] = [];
let extraInfo: any[] = [];
const mapping: {[key: string]: string} = {};

for (const item of docs) {
switch (item.NativeClass) {
function mapNameType(className: string, type: string): string {
return className;
/*const match = className.match(/\w+_(.*)_C/);
if (!match) {
throw new Error('Invliad className: ' + className);
}
const key = Strings.webalize(type + ' ' + match[1]);
if (className in mapping && mapping[className] !== key) {
throw new Error('Duplicated className: ' + className);
}
return mapping[className] = key;*/
}

for (const definitions of docs) {
switch (definitions.NativeClass) {
case 'Class\'/Script/FactoryGame.FGItemDescriptor\'':
case 'Class\'/Script/FactoryGame.FGEquipmentDescriptor\'':
case 'Class\'/Script/FactoryGame.FGConsumableDescriptor\'':
case 'Class\'/Script/FactoryGame.FGItemDescriptorNuclearFuel\'':
json.items.push(...parseItemDescriptors(item.Classes));
for (const item of parseItemDescriptors(definitions.Classes)) {
json.items[mapNameType(item.className, 'item')] = item;
}
break;
case 'Class\'/Script/FactoryGame.FGRecipe\'':
json.recipes.push(...parseRecipes(item.Classes));
for (const recipe of parseRecipes(definitions.Classes)) {
json.recipes[mapNameType(recipe.className, 'recipe')] = recipe;
}
break;
case 'Class\'/Script/FactoryGame.FGResourceDescriptor\'':
json.items.push(...parseItemDescriptors(item.Classes));
json.resources.push(...parseResourceDescriptors(item.Classes));
for (const item of parseItemDescriptors(definitions.Classes)) {
json.items[mapNameType(item.className, 'item')] = item;
}
for (const resource of parseResourceDescriptors(definitions.Classes)) {
json.resources[mapNameType(resource.item, 'item')] = resource;
}
break;
case 'Class\'/Script/FactoryGame.FGItemDescriptorBiomass\'':
biomass = parseItemDescriptors(item.Classes);
json.items.push(...biomass);
biomass = parseItemDescriptors(definitions.Classes);
for (const item of biomass) {
json.items[mapNameType(item.className, 'item')] = item;
}
break;
case 'Class\'/Script/FactoryGame.FGVehicleDescriptor\'':
json.buildings.push(...parseBuildings(item.Classes));
for (const building of parseBuildings(definitions.Classes)) {
json.buildings[mapNameType(building.className, 'building')] = building;
}
break;
case 'Class\'/Script/FactoryGame.FGBuildablePole\'':
case 'Class\'/Script/FactoryGame.FGBuildableConveyorBelt\'':
Expand Down Expand Up @@ -79,45 +107,96 @@ for (const item of docs) {
case 'Class\'/Script/FactoryGame.FGBuildableTrainPlatformEmpty\'':
case 'Class\'/Script/FactoryGame.FGBuildableSplitterSmart\'':
case 'Class\'/Script/FactoryGame.FGBuildableWalkway\'':
json.buildings.push(...parseBuildings(item.Classes, true));
for (const building of parseBuildings(definitions.Classes, true)) {
json.buildings[mapNameType(building.className, 'building')] = building;
}
break;
case 'Class\'/Script/FactoryGame.FGBuildableResourceExtractor\'':
json.miners.push(...parseResourceExtractors(item.Classes));
json.buildings.push(...parseBuildings(item.Classes, true));
for (const miner of parseResourceExtractors(definitions.Classes)) {
json.miners[mapNameType(miner.className, 'building')] = miner;
}
for (const building of parseBuildings(definitions.Classes, true)) {
json.buildings[mapNameType(building.className, 'building')] = building;
}
break;
case 'Class\'/Script/FactoryGame.FGBuildableGeneratorFuel\'':
case 'Class\'/Script/FactoryGame.FGBuildableGeneratorNuclear\'':
case 'Class\'/Script/FactoryGame.FGBuildableGeneratorGeoThermal\'':
json.buildings.push(...parseBuildings(item.Classes, true));
json.generators.push(...parseGenerators(item.Classes));
for (const building of parseBuildings(definitions.Classes, true)) {
json.buildings[mapNameType(building.className, 'building')] = building;
}
for (const generator of parseGenerators(definitions.Classes)) {
json.generators[mapNameType(generator.className, 'building')] = generator;
}
break;
case 'Class\'/Script/FactoryGame.FGBuildingDescriptor\'':
extraInfo = parseBuildingDescriptors(item.Classes);
extraInfo = parseBuildingDescriptors(definitions.Classes);
break;
case 'Class\'/Script/FactoryGame.FGSchematic\'':
for (const schematic of parseSchematics(definitions.Classes)) {
json.schematics[mapNameType(schematic.className, 'schematic')] = schematic;
}
break;
}
}

// add missing radar tower
json.buildings['Desc_RadarTower_C'] = {
className: 'Desc_RadarTower_C',
categories: [],
buildMenuPriority: 0,
description: 'Reveals an area around itself on the map. The area grows over time to a max. Placing the tower higher up increases the max area revealed.',
slug: 'radarTower',
metadata: {},
name: 'Radar Tower',
};

// add extra info to buildings
for (const info of extraInfo) {
for (const building of json.buildings) {
if (info.className === building.className) {
building.buildMenuPriority = info.priority;
building.categories = info.categories;
for (const key in json.buildings) {
if (info.className === json.buildings[key].className) {
json.buildings[key].buildMenuPriority = info.priority;
json.buildings[key].categories = info.categories;
break;
}
}
}

for (const generator of json.generators) {
const index = generator.fuel.indexOf('FGItemDescriptorBiomass');
// add biomass stuff to biomass burner
for (const key in json.generators) {
const index = json.generators[key].fuel.indexOf('FGItemDescriptorBiomass');
if (index !== -1) {
generator.fuel.splice(index, 1);
generator.fuel.push(...biomass.map((bio) => {
json.generators[key].fuel.splice(index, 1);
json.generators[key].fuel.push(...biomass.map((bio) => {
return bio.className;
}));
}
}

function findItem(className: string) {
// convert liquid requirements to m3
for (const key in json.recipes) {
const recipe = json.recipes[key];

for (const ingredient of recipe.ingredients) {
if (!json.items[ingredient.item]) {
throw new Error('Invalid item ' + ingredient.item);
}
if (json.items[ingredient.item].liquid) {
ingredient.amount /= 1000;
}
}
for (const product of recipe.products) {
if (!json.items[product.item]) {
continue;
}
if (json.items[product.item].liquid) {
product.amount /= 1000;
}
}
}


/*function findItem(className: string) {
if (className.match(/PowerPoleWall/) || className === 'Desc_RadarTower_C') {
return true;
}
Expand All @@ -133,11 +212,11 @@ function findItem(className: string) {
}
}
return false;
}
}*/

fs.writeFileSync(path.join(__dirname, '..', 'data', 'data.json'), JSON.stringify(json, null, '\t'));

for (const recipe of json.recipes) {
/*for (const recipe of json.recipes) {
for (const ingredient of recipe.ingredients) {
if (!findItem(ingredient.item)) {
throw new Error('Unknown item ' + ingredient.item);
Expand All @@ -148,4 +227,4 @@ for (const recipe of json.recipes) {
throw new Error('Unknown item ' + product.item);
}
}
}
}*/
2 changes: 1 addition & 1 deletion bin/parseDocs/building.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default function parseBuildings(buildings: {
}

result.push({
key: Strings.webalize(building.mDisplayName),
slug: Strings.webalize(building.mDisplayName),
name: building.mDisplayName,
description: building.mDescription.replace(/\r\n/ig, '\n'),
categories: [],
Expand Down
10 changes: 9 additions & 1 deletion bin/parseDocs/recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ export default function parseRecipes(recipes: {
{
const result: IRecipeSchema[] = [];
for (const recipe of recipes) {
const producedIn = Arrays.ensureArray(Strings.unserializeDocs(recipe.mProducedIn)).map(parseBlueprintClass).map((className: string) => {
return className.replace('Build_', 'Desc_');
});

// ignore converter recipes
if (producedIn.indexOf('Desc_Converter_C') !== -1) {
continue;
}
result.push({
slug: Strings.webalize(recipe.mDisplayName),
name: recipe.mDisplayName,
Expand All @@ -25,7 +33,7 @@ export default function parseRecipes(recipes: {
manualTimeMultiplier: parseFloat(recipe.mManualManufacturingMultiplier),
ingredients: Arrays.ensureArray(Strings.unserializeDocs(recipe.mIngredients)).map(parseItemAmount),
products: Arrays.ensureArray(Strings.unserializeDocs(recipe.mProduct)).map(parseItemAmount),
producedIn: Arrays.ensureArray(Strings.unserializeDocs(recipe.mProducedIn)).map(parseBlueprintClass),
producedIn: producedIn,
});
}
return result;
Expand Down
2 changes: 2 additions & 0 deletions bin/parseDocs/resourceExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Strings} from '@src/Utils/Strings';
import parseBlueprintClass from '@bin/parseDocs/blueprintClass';

export default function parseResourceExtractors(resourceExtractors: {
ClassName: string,
mAllowedResources: string,
mAllowedResourceForms: string,
mItemsPerCycle: string,
Expand All @@ -24,6 +25,7 @@ export default function parseResourceExtractors(resourceExtractors: {
}

const minerSchema: IMinerSchema = {
className: resourceExtractor.ClassName,
allowedResources: [],
itemsPerCycle: parseFloat(resourceExtractor.mItemsPerCycle),
allowLiquids: allowLiquids,
Expand Down
32 changes: 32 additions & 0 deletions bin/parseDocs/schematic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {ISchematicSchema} from '@src/Schema/ISchematicSchema';
import {Arrays} from '@src/Utils/Arrays';
import {Strings} from '@src/Utils/Strings';
import parseBlueprintClass from '@bin/parseDocs/blueprintClass';
import parseItemAmount from '@bin/parseDocs/itemAmount';

export default function parseSchematics(schematics: {
ClassName: string,
mType: string,
mTechTier: string,
mDisplayName: string,
mCost: string,
mUnlocks: string,
mShipTravelTimeAfterPurchase: string
}[]): ISchematicSchema[]
{
const result: ISchematicSchema[] = [];
for (const schematic of schematics) {
result.push({
className: schematic.ClassName,
name: schematic.mDisplayName,
tier: parseInt(schematic.mTechTier),
cost: schematic.mCost ? Arrays.ensureArray(Strings.unserializeDocs(schematic.mCost)).map(parseItemAmount) : [],
unlock: schematic.mUnlocks ? Arrays.ensureArray(Strings.unserializeDocs(schematic.mUnlocks)).map(parseBlueprintClass) : [],
type: schematic.mType,
time: parseFloat(schematic.mShipTravelTimeAfterPurchase),
alternate: false,
mam: false,
});
}
return result;
}
Loading

0 comments on commit c98a3e8

Please sign in to comment.