Skip to content

Commit

Permalink
Added Build Mimic Model Tool
Browse files Browse the repository at this point in the history
  • Loading branch information
jamiephan committed Jan 11, 2021
1 parent 2bd95e2 commit df4c924
Show file tree
Hide file tree
Showing 6 changed files with 76,515 additions and 0 deletions.
76,295 changes: 76,295 additions & 0 deletions (10)trymemode.stormmap/base.stormdata/Mods/HeroesMod/ModelMimic.xml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
HEROES_OF_THE_STORM_INSTALL_LOCATION="/mnt/g/Heroes of the Storm/"
TOOLS_MIMC_ABILITY_XML_GENERATION_LOCATION="./(10)trymemode.stormmap/base.stormdata/Mods/HeroesMod/AbilityMimic.xml"
TOOLS_MIMC_BEHAVIOR_XML_GENERATION_LOCATION="./(10)trymemode.stormmap/base.stormdata/Mods/HeroesMod/BehaviorMimic.xml"
TOOLS_MIMC_MODEL_XML_GENERATION_LOCATION="./(10)trymemode.stormmap/base.stormdata/Mods/HeroesMod/ModelMimic.xml"
TOOLS_XML_MAIN_XML_PATH="./(10)trymemode.stormmap/base.stormdata/GameData.xml"
TOOLS_XML_MODS_DIR="./(10)trymemode.stormmap/base.stormdata/Mods"
TOOLS_GAMEDATA_DIR="./(10)trymemode.stormmap/base.stormdata"
Expand Down
19 changes: 19 additions & 0 deletions TOOLS.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ The current values required are:
| `TOOLS_UPDATE_LIBRARY_LIBRARIES_LOCATION` | String | The location of the galaxy modules. Default: `./(10)trymemode.stormmap/base.stormdata/Modules` |
| `TOOLS_MIMC_ABILITY_XML_GENERATION_LOCATION` | String | The location which Mimic Ability tool will produce. Please have it inside `TOOLS_XML_MODS_DIR` (Any level subdirectory does not matter). Default: `./(10)trymemode.stormmap/base.stormdata/Mods/HeroesMod/AbilityMimic.xml` |
| `TOOLS_MIMC_BEHAVIOR_XML_GENERATION_LOCATION` | String | The location which Mimic Behavior tool will produce. Please have it inside `TOOLS_XML_MODS_DIR` (Any level subdirectory does not matter). Default: `./(10)trymemode.stormmap/base.stormdata/Mods/HeroesMod/BehaviorMimic.xml` |
| `TOOLS_MIMC_MODEL_XML_GENERATION_LOCATION` | String | The location which Mimic Model tool will produce. Please have it inside `TOOLS_XML_MODS_DIR` (Any level subdirectory does not matter). Default: `./(10)trymemode.stormmap/base.stormdata/Mods/HeroesMod/ModelMimic.xml` |


>Note: Generally, only modifying `HEROES_OF_THE_STORM_INSTALL_LOCATION` is enough, which its the install location for Heroes of the Storm under Linux / WSL path. (e.g in WSL, the letter drive will mount to `/mnt/{drive}`, so `C:/Program Files/Heroes of the Storm` will be `/mnt/c/Program Files/Heroes of the Storm`.)
Expand Down Expand Up @@ -123,6 +124,24 @@ Generated XML file location: `./(10)trymemode.stormmap/base.stormdata/Mods/Heroe
Altering `.env` variable: `TOOLS_MIMC_BEHAVIOR_XML_GENERATION_LOCATION`


---
<a name="tools-buildmimicmodels" />

## `<CModel>` Mimic Generator

**Command**: `npm run build:mimicmodels`

This tool will search though all the `<CModel>` and map it to a `<CUnit>`, which allows to be controlled on the map.

This will generate a unit with the prefixed `UN`. For instance, the model `RetreatPing` (White Flag retreat ping model) will have a unit `UNRetreatPing`, which you can summon this unit using tools such as [summon](USAGE.md#cmd-summon), with the command of `summon UNRetreatPing`.

>Note: After generation, it will run a function similar to `npm run buildxml` once, since its a XML mod after all.
Generated XML file location: `./(10)trymemode.stormmap/base.stormdata/Mods/HeroesMod/ModelMimic.xml`

Altering `.env` variable: `TOOLS_MIMC_MODEL_XML_GENERATION_LOCATION`


---
<a name="tools-buildxml" />

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"build:mimiclib": "bash -c -i \"node ./scripts/main/buildmimiclib.js\"",
"build:mimicabilities": "bash -c -i \"node ./scripts/main/buildmimicabilities.js\"",
"build:mimicbehaviors": "bash -c -i \"node ./scripts/main/buildmimicbehaviors.js\"",
"build:mimicmodels": "bash -c -i \"node ./scripts/main/buildmimicmodels.js\"",
"build:usagedoc": "bash -c -i \"node ./scripts/main/buildusagedoc.js\"",
"watch:usagedoc": "bash -c -i \"node ./scripts/watch/usagedoc.js\"",
"patch:libraries": "bash -c -i \"node ./scripts/main/patchlibraries.js\"",
Expand Down
66 changes: 66 additions & 0 deletions scripts/main/buildmimicmodels.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const buildMimicXML = require('./helper/buildmimicXML');

const prefix = 'UN';

buildMimicXML({
catalogTypeRegex: /^CModel/i,
saveLocation: process.env.TOOLS_MIMC_MODEL_XML_GENERATION_LOCATION,
generation: {
header: {
generatedCommand: 'npm run build:mimicmodels',
description: [
'It will find all <CModel*> and map to a <CUnit>,',
'That allow a model to be spawned as a Unit.',
`To prevent collision, all Mimic Models Unit's id will have prefixed "${prefix}"`,
],
},
pre: [
{
CUnit: {
$: {
id: `${prefix}_t`,
parent: 'StormHero',
},
BehaviorArray: [
{
$: { Link: 'PermaInvulnerable' },
},
],
WeaponArray: [
{
$: { Link: 'FootmanMinion' },
},
],
},
},
],
main: (type, xmlData) => {
const { id } = xmlData.$;
// console.log(`Mapped Model ${id} to Unit ${prefix}${id}.`);
return [
{
CUnit: {
$: {
id: `${prefix}${id}`,
parent: `${prefix}_t`,
},
},
},
{
CActorUnit: {
$: {
id: `${prefix}${id}`,
parent: 'GenericUnitStandard',
unitName: `${prefix}${id}`,
},
Model: {
$: {
value: id,
},
},
},
},
];
},
},
});
133 changes: 133 additions & 0 deletions scripts/main/helper/buildmimicXML.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/* eslint-disable require-jsdoc */
const xml2js = require('xml2js');
const fs = require('fs');
const path = require('path');
const HeroesFiles = require('./HeoresFileWalker');
const autoXMLinclude = require('./autoXMLinclude');

module.exports = (configParam) => {
const config = {
filesSearchRegex: HeroesFiles.AllXMLs,
catalogTypeRegex: /^CAbilEffectTarget/i,
saveLocation: './default.xml',
generation: {
header: {
generatedCommand: 'npm run xxxx',
description: 'Completely devoid of any description whatsoever.',
},
pre: [],
main: (type, xmlData) => ({ [type]: xmlData }),
},
...configParam,
};

// ================= Generation of file =================

// xml2js.Builder() does not allow to add comments...
const builder = new xml2js.Builder({
rootName: 'Catalog',
xmldec: {
version: '1.0',
encoding: 'us-ascii',
standalone: false,
},
});

const mainObj = {};

if (config.generation.pre !== null) {
config.generation.pre.forEach((o) => {
// Check if key exist
const key = Object.keys(o);
if (mainObj[key] === undefined) mainObj[key] = [];
mainObj[key].push(o[key]);
});
}

HeroesFiles
.ReadEach(config.filesSearchRegex)
.forEach((file) => {
xml2js.parseString(file.fileData, (error, result) => {
if (error) throw error;

// Main <Catalog> data
const catalog = result.Catalog;
if (catalog === undefined || catalog === null) return;

// Read of the entry, such as <CBehaviorBuff>, <CAbilEffectInstant> ...
Object.entries(catalog)
.forEach((entries) => {
// e.g BehaviorBuff
const catalogType = entries[0];
// Does not match type
if (!config.catalogTypeRegex.test(catalogType)) return;

entries[1].forEach((entry) => {
const catalogEntry = entry.$.id;
if (catalogEntry === undefined || catalogEntry === null) return;

// Returned function
const obj = config.generation.main(catalogType, entry);

if (obj === undefined || obj === null || !Array.isArray(obj)) return;

obj.forEach((o) => {
// Check if key exist
const key = Object.keys(o);
if (mainObj[key] === undefined) mainObj[key] = [];
mainObj[key].push(o[key]);
});
});
});
});
});

let finalXML = builder.buildObject(mainObj);

// Inject Comments into the built XML, since builder does not support adding comments

finalXML = finalXML.split('\n');

let { description } = config.generation.header;

if (typeof description === 'string') {
description = description.split('\n');
}

finalXML[0] = `${finalXML[0]}
<!-- ======================================================== -->
<!-- This file is generated via "${config.generation.header.generatedCommand}" -->
<!-- ======================================================== -->
${description
.map((d) => `<!-- ${d} -->`)
.join('\n')
}
`;
finalXML = finalXML.join('\n');

console.log('===================');

// Check if parent directory exist
if (!fs.existsSync(path.dirname(config.saveLocation))) {
fs.mkdirSync(
path.dirname(config.saveLocation), {
recursive: true,
},
);
console.log(`Created directory: ${path.dirname(config.saveLocation)}`);
}

// Save file
fs.writeFileSync(
config.saveLocation,
finalXML,
{ encoding: 'utf8' },
);

console.log(`Created file: ${config.saveLocation}`);
console.log('===================');

// Generate XML
autoXMLinclude();
};

0 comments on commit df4c924

Please sign in to comment.