mirror of
https://github.com/theBowja/GenshinData-1.git
synced 2025-04-29 02:28:36 +09:00
yuck
This commit is contained in:
parent
b0c25fef63
commit
4172a7477c
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/node_modules
|
420
myscript.js
420
myscript.js
@ -1,420 +0,0 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const xavatar = require(".../ExcelBinOutput/AvatarExcelConfigData.json"); // array
|
||||
// avatar extra info
|
||||
const xextrainfo = require('.../ExcelBinOutput/FetterInfoExcelConfigData.json');
|
||||
|
||||
const xskilldepot = require('.../ExcelBinOutput/AvatarSkillDepotExcelConfigData.json');
|
||||
const xtalent = require('.../ExcelBinOutput/AvatarSkillExcelConfigData.json'); // combat talents
|
||||
const xpassive = require('.../ExcelBinOutput/ProudSkillExcelConfigData.json'); // passive talents
|
||||
const xconstellation = require('.../ExcelBinOutput/AvatarTalentExcelConfigData.json');
|
||||
|
||||
const xweapon = require('.../ExcelBinOutput/WeaponExcelConfigData.json');
|
||||
const xrefine = require('.../ExcelBinOutput/EquipAffixExcelConfigData.json');
|
||||
|
||||
const xmanualtext = getExcel('ManualTextMapConfigData'); //require('.../ExcelBinOutput/ManualTextMapConfigData.json');
|
||||
|
||||
const langcodes = ['CHS', 'CHT', 'DE', 'EN', 'ES', 'FR', 'ID', 'JA', 'KO', 'PT', 'RU', 'TH', 'VI'];
|
||||
|
||||
function getExcel(file) {
|
||||
return require(`.../ExcelBinOutput/${file}.json`);
|
||||
}
|
||||
|
||||
/* ========================================================================================== */
|
||||
|
||||
// object map that converts the genshin coded element into a TextMapHash
|
||||
const elementTextMapHash = ['Fire', 'Water', 'Grass', 'Electric', 'Wind', 'Ice', 'Rock'].reduce((accum, element) => {
|
||||
accum[element] = xmanualtext.find(ele => ele.TextMapId === element).TextMapContentTextMapHash;
|
||||
return accum;
|
||||
}, {});
|
||||
|
||||
const xplayableWeapon = xweapon.filter(obj => {
|
||||
if(obj.RankLevel >= 3 && obj.SkillAffix[0] === 0) return false;
|
||||
if(obj.SkillAffix[1] !== 0) { console.log('danger'); return false };
|
||||
if(getLanguage('EN')[obj.NameTextMapHash] === '') return false;
|
||||
return true;
|
||||
})
|
||||
|
||||
const xplayableAvatar = xavatar.filter(obj => obj.AvatarPromoteId !== 2); // array
|
||||
// object map that converts an avatar Id or traveler SkillDepotId to filename
|
||||
const avatarIdToFileName = xplayableAvatar.reduce((accum, obj) => {
|
||||
if(obj.Id === 10000005) accum[obj.Id] = 'aether';
|
||||
else if(obj.Id === 10000007) accum[obj.Id] = 'lumine';
|
||||
else accum[obj.Id] = makeFileName(getLanguage('EN')[obj.NameTextMapHash]);
|
||||
if(isPlayer(obj)) { //
|
||||
obj.CandSkillDepotIds.forEach(skdeId => {
|
||||
let trelement = elementTextMapHash[getPlayerElement(skdeId)];
|
||||
if(trelement === undefined) return;
|
||||
accum[skdeId] = makeFileName(getLanguage('EN')[obj.NameTextMapHash] + getLanguage('EN')[trelement]);
|
||||
})
|
||||
}
|
||||
return accum;
|
||||
}, {});
|
||||
|
||||
// const weaponIdToFileName = xweapon.reduce((accum, obj) => {
|
||||
// accum[obj.Id] =
|
||||
|
||||
// }, {})
|
||||
|
||||
// object map that converts a WeaponType into a TextMapHash
|
||||
const weaponTextMapHash = ['WEAPON_SWORD_ONE_HAND', 'WEAPON_CATALYST', 'WEAPON_CLAYMORE', 'WEAPON_BOW', 'WEAPON_POLE'].reduce((accum, str) => {
|
||||
accum[str] = xmanualtext.find(ele => ele.TextMapId === str).TextMapContentTextMapHash;
|
||||
return accum;
|
||||
}, {});
|
||||
|
||||
// UNUSED object map that converts AvatarAssocType into a TextMapHash
|
||||
const assocTextMapHash = ['ASSOC_TYPE_MONDSTADT', 'ASSOC_TYPE_LIYUE', 'ASSOC_TYPE_FATUI'];
|
||||
|
||||
// object map that converts relic EquipType to a property name
|
||||
const relicTypeToPropertyName = { 'EQUIP_BRACER': 'flower', 'EQUIP_NECKLACE': 'plume', 'EQUIP_SHOES': 'sands', 'EQUIP_RING': 'goblet', 'EQUIP_DRESS': 'circlet'};
|
||||
|
||||
// object map that converts index to the talent type
|
||||
const talentCombatTypeMap = { '0': 'combat1', '1': 'combat2', '2': 'combatsp', '4': 'combat3' };
|
||||
|
||||
// object map that converts player's avatar id to TextMapHash
|
||||
const playerIdToTextMapHash = { 10000005: 2329553598, 10000007: 3241049361 };
|
||||
|
||||
function isPlayer(data) { return data.CandSkillDepotIds.length !== 0; }
|
||||
function getPlayerElement(SkillDepotId) { let tmp = xskilldepot.find(ele => ele.Id === SkillDepotId); return tmp === undefined ? tmp : tmp.TalentStarName.split('_').pop(); }
|
||||
function getLanguage(abbriev) { return require("./TextMap/Text"+abbriev.toUpperCase()+".json"); }
|
||||
function makeFileName(str) { return str.toLowerCase().replace(/[^a-z]/g,''); }
|
||||
function convertBold(str) { return str.replace(/<color=#FFD780FF>(.*?)<\/color>/gi, '**$1**'); }
|
||||
function stripHTML(str) { return str.replace(/(<([^>]+)>)/gi, ''); }
|
||||
function capitalizeFirst(str) { return str[0].toUpperCase() + str.toLowerCase().slice(1); }
|
||||
function replaceLayout(str) { return str.replace(/{LAYOUT_MOBILE#Tap}{LAYOUT_PC#Press}{LAYOUT_PS#Press}/gi,'Press').replace('#',''); }
|
||||
function replaceNewline(str) { return str.replace(/\\n/gi, '\n'); }
|
||||
function sanitizeDescription(str) { return replaceNewline(replaceLayout(stripHTML(convertBold(str)))); }
|
||||
|
||||
function collateCharacter(lang) {
|
||||
const language = getLanguage(lang);
|
||||
const xsubstat = require('.../ExcelBinOutput/AvatarPromoteExcelConfigData.json');
|
||||
let myavatar = xplayableAvatar.reduce((accum, obj) => {
|
||||
let data = {};
|
||||
let extra = xextrainfo.find(ele => ele.AvatarId === obj.Id);
|
||||
|
||||
data.name = language[obj.NameTextMapHash];
|
||||
if(isPlayer(obj)) data.name = language[playerIdToTextMapHash[obj.Id]];
|
||||
//if(data.name === 'Traveler') data.name = capitalizeFirst(avatarIdToFileName[obj.Id]);
|
||||
data.description = language[obj.DescTextMapHash];
|
||||
data.weapontype = language[weaponTextMapHash[obj.WeaponType]];
|
||||
data.body = obj.BodyType.slice(obj.BodyType.indexOf('BODY_')+5);
|
||||
data.rarity = obj.QualityType === 'QUALITY_PURPLE' ? '4' : '5';
|
||||
data.birthmonth = extra.InfoBirthMonth;
|
||||
data.birthday = extra.InfoBirthDay;
|
||||
data.affiliation = isPlayer(obj) ? '' : language[extra.AvatarNativeTextMapHash];
|
||||
data.element = language[extra.AvatarVisionBeforTextMapHash];
|
||||
data.constellation = language[extra.AvatarConstellationBeforTextMapHash];
|
||||
if(obj.Id === 10000030) data.constellation = language[extra.AvatarConstellationAfterTextMapHash]; // Zhongli exception
|
||||
data.title = language[extra.AvatarTitleTextMapHash];
|
||||
data.association = extra.AvatarAssocType.slice(extra.AvatarAssocType.indexOf('TYPE_')+5);
|
||||
data.cv = {
|
||||
english: language[extra.CvEnglishTextMapHash],
|
||||
chinese: language[extra.CvChineseTextMapHash],
|
||||
japanese: language[extra.CvJapaneseTextMapHash],
|
||||
korean: language[extra.CvKoreanTextMapHash]
|
||||
};
|
||||
|
||||
const xsubstat = require('.../ExcelBinOutput/AvatarPromoteExcelConfigData.json');
|
||||
const xmanualtext = require('.../ExcelBinOutput/ManualTextMapConfigData.json');
|
||||
|
||||
let substat = xsubstat.find(ele => ele.AvatarPromoteId === obj.AvatarPromoteId).AddProps[3].PropType;
|
||||
data.substat = language[xmanualtext.find(ele => ele.TextMapId === substat).TextMapContentTextMapHash];
|
||||
|
||||
data.icon = obj.IconName;
|
||||
data.sideicon = obj.SideIconName;
|
||||
|
||||
// INFORMATION TO CALCULATE STATS AT EACH LEVEL
|
||||
let stats = { base: {}, curve: {} };
|
||||
stats.base.hp = obj.HpBase;
|
||||
stats.base.attack = obj.AttackBase;
|
||||
stats.base.defense = obj.DefenseBase;
|
||||
stats.base.critrate = obj.Critical;
|
||||
stats.base.critdmg = obj.CriticalHurt;
|
||||
|
||||
stats.curve.hp = obj.PropGrowCurves.find(ele => ele.Type === 'FIGHT_PROP_BASE_HP').GrowCurve;
|
||||
stats.curve.attack = obj.PropGrowCurves.find(ele => ele.Type === 'FIGHT_PROP_BASE_ATTACK').GrowCurve;
|
||||
stats.curve.defense = obj.PropGrowCurves.find(ele => ele.Type === 'FIGHT_PROP_BASE_DEFENSE').GrowCurve;
|
||||
stats.specialized = substat;
|
||||
stats.promotion = xsubstat.reduce((accum, ele) => {
|
||||
if(ele.AvatarPromoteId !== obj.AvatarPromoteId) return accum;
|
||||
let promotelevel = ele.PromoteLevel || 0;
|
||||
accum[promotelevel] = {
|
||||
maxlevel: ele.UnlockMaxLevel,
|
||||
hp: ele.AddProps.find(ele => ele.PropType === 'FIGHT_PROP_BASE_HP').Value || 0,
|
||||
attack: ele.AddProps.find(ele => ele.PropType === 'FIGHT_PROP_BASE_ATTACK').Value || 0,
|
||||
defense: ele.AddProps.find(ele => ele.PropType === 'FIGHT_PROP_BASE_DEFENSE').Value || 0,
|
||||
specialized: ele.AddProps.find(ele => ele.PropType === substat).Value || 0,
|
||||
};
|
||||
return accum;
|
||||
}, []);
|
||||
data.stats = stats;
|
||||
|
||||
accum[avatarIdToFileName[obj.Id]] = data;
|
||||
return accum;
|
||||
}, {})
|
||||
return myavatar;
|
||||
}
|
||||
|
||||
function collateConstellation(lang) {
|
||||
const language = getLanguage(lang);
|
||||
let myconstellation = xplayableAvatar.reduce((accum, obj) => {
|
||||
// bad practice to declare functions inside loop but i need to be able to call it multiple times for players
|
||||
function dowork() {
|
||||
let data = {};
|
||||
let depot = xskilldepot.find(ele => ele.Id === obj.SkillDepotId);
|
||||
if(depot === undefined || depot.EnergySkill === undefined) return; // not a finished (traveler) character
|
||||
if(depot.TalentStarName === '') return; // unfinished
|
||||
|
||||
data.name = language[obj.NameTextMapHash];
|
||||
if(isPlayer(obj)) data.name += ` (${language[elementTextMapHash[getPlayerElement(obj.SkillDepotId)]]})`
|
||||
//console.log(depot)
|
||||
data.images = {};
|
||||
let stars = depot.Talents.map(talentId => xconstellation.find(ele => ele.TalentId === talentId));
|
||||
for(let i = 1; i <= 6; i++) {
|
||||
data['c'+i] = {
|
||||
name: language[stars[i-1].NameTextMapHash],
|
||||
effect: sanitizeDescription(language[stars[i-1].DescTextMapHash])
|
||||
};
|
||||
data.images['c'+i] = `https://upload-os-bbs.mihoyo.com/game_record/genshin/constellation_icon/${stars[i-1].Icon}.png`;
|
||||
}
|
||||
|
||||
accum[avatarIdToFileName[isPlayer(obj) ? obj.SkillDepotId : obj.Id]] = data;
|
||||
}
|
||||
|
||||
if(isPlayer(obj)) {
|
||||
obj.CandSkillDepotIds.forEach(ele => {
|
||||
obj.SkillDepotId = ele;
|
||||
dowork();
|
||||
});
|
||||
} else {
|
||||
dowork();
|
||||
}
|
||||
return accum;
|
||||
}, {});
|
||||
return myconstellation;
|
||||
}
|
||||
|
||||
function collateTalent(lang) {
|
||||
const language = getLanguage(lang);
|
||||
let mytalent = xplayableAvatar.reduce((accum, obj) => {
|
||||
// bad practice to declare functions inside loop but i need to be able to call it multiple times for players
|
||||
function dowork() {
|
||||
let data = {};
|
||||
let depot = xskilldepot.find(ele => ele.Id === obj.SkillDepotId);
|
||||
if(depot === undefined || depot.EnergySkill === undefined) return; // not a finished (traveler) character
|
||||
if(depot.TalentStarName === '') return; // unfinished
|
||||
|
||||
data.name = language[obj.NameTextMapHash]; // client-facing name
|
||||
if(isPlayer(obj)) data.name += ` (${language[elementTextMapHash[getPlayerElement(obj.SkillDepotId)]]})`
|
||||
|
||||
let combat = depot.Skills.concat([depot.EnergySkill]) // get array of combat skills IDs
|
||||
let passive = depot.InherentProudSkillOpens.reduce((accum2, proud) => { // get array of passive skill IDs
|
||||
if(proud.ProudSkillGroupId) accum2.push(proud.ProudSkillGroupId);
|
||||
return accum2;
|
||||
}, [])
|
||||
|
||||
combat.forEach((skId, index) => {
|
||||
if(skId === 0) return;
|
||||
let talent = xtalent.find(tal => tal.Id === skId);
|
||||
let ref = data[talentCombatTypeMap[index]] = {};
|
||||
|
||||
ref.name = language[talent.NameTextMapHash];
|
||||
let desc = language[talent.DescTextMapHash].split('\\n\\n<i>'); // extract out the italicized part
|
||||
ref.info = sanitizeDescription(desc[0]);
|
||||
if(desc[1]) ref.description = sanitizeDescription(desc[1]);
|
||||
});
|
||||
|
||||
passive.forEach((skId, index) => {
|
||||
let talent = xpassive.find(pas => pas.ProudSkillGroupId === skId);
|
||||
let ref = data['passive'+(index+1)] = {}; // store reference in variable to make it easier to access
|
||||
|
||||
ref.name = language[talent.NameTextMapHash];
|
||||
ref.info = sanitizeDescription(language[talent.DescTextMapHash]);
|
||||
});
|
||||
|
||||
accum[avatarIdToFileName[isPlayer(obj) ? obj.SkillDepotId : obj.Id]] = data;
|
||||
}
|
||||
|
||||
if(isPlayer(obj)) {
|
||||
obj.CandSkillDepotIds.forEach(ele => {
|
||||
obj.SkillDepotId = ele;
|
||||
dowork();
|
||||
});
|
||||
} else {
|
||||
dowork();
|
||||
}
|
||||
return accum;
|
||||
}, {});
|
||||
return mytalent;
|
||||
}
|
||||
|
||||
function collateWeapon(lang) {
|
||||
const language = getLanguage(lang);
|
||||
const xsubstat = require('.../ExcelBinOutput/WeaponPromoteExcelConfigData.json');
|
||||
let myweapon = xplayableWeapon.reduce((accum, obj) => {
|
||||
|
||||
let data = {};
|
||||
|
||||
data.name = language[obj.NameTextMapHash];
|
||||
data.description = language[obj.DescTextMapHash];
|
||||
data.weapontype = language[weaponTextMapHash[obj.WeaponType]];
|
||||
data.rarity = ''+obj.RankLevel;
|
||||
|
||||
if(obj.WeaponProp[0].PropType !== 'FIGHT_PROP_BASE_ATTACK') console.log(obj,'weapon did not find base atk');
|
||||
data.baseatk = obj.WeaponProp.find(obj => obj.PropType === 'FIGHT_PROP_BASE_ATTACK').InitValue;
|
||||
|
||||
let substat = obj.WeaponProp[1].PropType;
|
||||
if(substat !== undefined) {
|
||||
data.substat = language[xmanualtext.find(ele => ele.TextMapId === substat).TextMapContentTextMapHash];
|
||||
let subvalue = obj.WeaponProp[1].InitValue;
|
||||
data.subvalue = subvalue;
|
||||
}
|
||||
|
||||
if(obj.SkillAffix[0] !== 0) {
|
||||
let affixId = obj.SkillAffix[0] * 10;
|
||||
for(let offset = 0; offset < 5; offset++) {
|
||||
let ref = xrefine.find(ele => ele.AffixId === affixId+offset);
|
||||
if(ref === undefined) break;
|
||||
if(offset === 0) data.effectname = language[ref.NameTextMapHash];
|
||||
let effect = language[ref.DescTextMapHash];
|
||||
effect = effect.replace(/<color=#.*?>/gi, '{').replace(/<\/color>/gi, '}');
|
||||
effect = effect.split(/{|}/);
|
||||
data['r'+(offset+1)] = [];
|
||||
data['effect'] = effect.reduce((accum, ele, i) => {
|
||||
if(i % 2 === 0) {
|
||||
return accum + ele;
|
||||
} else {
|
||||
data['r'+(offset+1)].push(ele);
|
||||
return accum + `{${(i-1)/2}}`;
|
||||
}
|
||||
}, '');
|
||||
}
|
||||
}
|
||||
|
||||
// INFORMATION TO CALCULATE STATS AT EACH LEVEL
|
||||
let stats = { base: {}, curve: {} };
|
||||
stats.base.attack = obj.WeaponProp[0].InitValue;
|
||||
stats.base.specialized = obj.WeaponProp[1].InitValue || 0;
|
||||
|
||||
stats.curve.attack = obj.WeaponProp[0].Type;
|
||||
stats.curve.specialized = obj.WeaponProp[1].Type;
|
||||
stats.specialized = substat;
|
||||
stats.promotion = xsubstat.reduce((accum, ele) => {
|
||||
if(ele.WeaponPromoteId !== obj.WeaponPromoteId) return accum;
|
||||
let promotelevel = ele.PromoteLevel || 0;
|
||||
accum[promotelevel] = {
|
||||
maxlevel: ele.UnlockMaxLevel,
|
||||
attack: ele.AddProps.find(ele => ele.PropType === 'FIGHT_PROP_BASE_ATTACK').Value || 0
|
||||
};
|
||||
let special = ele.AddProps.find(ele => ele.PropType === substat);//.Value;
|
||||
if(special) special = special.Value;
|
||||
if(special !== undefined) {
|
||||
console.log('WEAPON SPECIAL SUBSTAT FOUND: ' + obj.Id)
|
||||
accum[promotelevel].specialized = special;
|
||||
}
|
||||
return accum;
|
||||
}, [])
|
||||
data.stats = stats;
|
||||
|
||||
data.icon = obj.Icon;
|
||||
data.awakenicon = obj.AwakenIcon;
|
||||
|
||||
let filename = makeFileName(getLanguage('EN')[obj.NameTextMapHash]);
|
||||
if(accum[filename] !== undefined) console.log(filename+' IS NOT UNIQUE');
|
||||
accum[filename] = data;
|
||||
return accum;
|
||||
}, {});
|
||||
|
||||
return myweapon;
|
||||
}
|
||||
|
||||
function collateArtifact(lang) {
|
||||
const language = getLanguage(lang);
|
||||
const xsets = require('.../ExcelBinOutput/ReliquarySetExcelConfigData.json');
|
||||
const xrelics = require('.../ExcelBinOutput/ReliquaryExcelConfigData.json');
|
||||
const xreliccodex = require('.../ExcelBinOutput/ReliquaryCodexExcelConfigData.json');
|
||||
const xrefine = require('.../ExcelBinOutput/EquipAffixExcelConfigData.json');
|
||||
|
||||
let myartifact = xsets.reduce((accum, obj) => {
|
||||
if(obj.SetIcon === '') return accum;
|
||||
let setname;
|
||||
let filename;
|
||||
let data = {};
|
||||
|
||||
// get available rarities
|
||||
data.rarity = xreliccodex.reduce((accum, relic) => {
|
||||
if(obj.SetId !== relic.SuitId) return accum;
|
||||
relic.Level = relic.Level.toString();
|
||||
if(accum.indexOf(relic.Level) === -1) accum.push(relic.Level);
|
||||
return accum;
|
||||
}, []);
|
||||
|
||||
// set bonus effects
|
||||
obj.SetNeedNum.forEach((ele, ind) => {
|
||||
let effect = xrefine.find(e => e.AffixId === obj.EquipAffixId*10 + ind);
|
||||
data[ele+'pc'] = language[effect.DescTextMapHash];
|
||||
if(setname === undefined) {
|
||||
setname = language[effect.NameTextMapHash];
|
||||
filename = makeFileName(getLanguage('EN')[effect.NameTextMapHash]);
|
||||
}
|
||||
});
|
||||
|
||||
data.images = {};
|
||||
// relic pieces
|
||||
obj.ContainsList.forEach(ele => {
|
||||
let relic = xrelics.find(e => e.Id === ele);
|
||||
let relicdata = {};
|
||||
relicdata.name = language[relic.NameTextMapHash];
|
||||
relicdata.relictype = xmanualtext.find(ele => ele.TextMapId === relic.EquipType).TextMapContentTextMapHash;
|
||||
relicdata.relictype = language[relicdata.relictype];
|
||||
relicdata.description = language[relic.DescTextMapHash];
|
||||
data[relicTypeToPropertyName[relic.EquipType]] = relicdata;
|
||||
data.images[relicTypeToPropertyName[relic.EquipType]] = `https://upload-os-bbs.mihoyo.com/game_record/genshin/equip/${relic.Icon}.png`;
|
||||
});
|
||||
|
||||
data.name = setname;
|
||||
accum[filename] = data;
|
||||
return accum;
|
||||
}, {});
|
||||
return myartifact;
|
||||
}
|
||||
|
||||
function exportCurve(folder, file) {
|
||||
const xcurve = require(file);
|
||||
let output = {};
|
||||
xcurve.forEach(ele => {
|
||||
let curveinfo = {};
|
||||
ele.CurveInfos.forEach(ele => {
|
||||
curveinfo[ele.Type] = ele.Value;
|
||||
});
|
||||
output[ele.Level] = curveinfo;
|
||||
});
|
||||
fs.mkdirSync(`./export/curve`, { recursive: true });
|
||||
fs.writeFileSync(`./export/curve/${folder}.json`, JSON.stringify(output, null, '\t'));
|
||||
}
|
||||
|
||||
function exportData(folder, collateFunc, englishonly) {
|
||||
langcodes.forEach(lang => {
|
||||
if(englishonly && lang !== 'EN') return;
|
||||
let data = collateFunc(lang);
|
||||
fs.mkdirSync(`./export/${lang}`, { recursive: true });
|
||||
fs.writeFileSync(`./export/${lang}/${folder}.json`, JSON.stringify(data, null, '\t'));
|
||||
if(JSON.stringify(data).search('undefined') !== -1) console.log('undefined found in '+folder);
|
||||
});
|
||||
console.log("done "+folder);
|
||||
}
|
||||
|
||||
exportData('characters', collateCharacter);
|
||||
exportCurve('characters', '.../ExcelBinOutput/AvatarCurveExcelConfigData.json');
|
||||
exportData('constellations', collateConstellation);
|
||||
exportData('talents', collateTalent);
|
||||
exportData('weapons', collateWeapon);
|
||||
exportCurve('weapons', '.../ExcelBinOutput/WeaponCurveExcelConfigData.json')
|
||||
exportData('artifacts', collateArtifact);
|
||||
exportData('foods', collateFood);
|
||||
|
||||
//console.log(collateCharacter('EN'))
|
||||
//console.log(collateConstellation('EN').hutao)
|
||||
//console.log(collateTalent('EN').mona)
|
||||
//console.log(collateWeapon('EN'));
|
||||
// console.log(collateArtifact('EN'));
|
@ -87,7 +87,7 @@ function collateDomain(lang) {
|
||||
data.name = language[obj.NameTextMapHash];
|
||||
// data.displayname = language[obj.DisplayNameTextMapHash]; // doesn't exist for artifact domains
|
||||
data.domainentrance = language[getDomainEntranceTextMapHash(getLanguage('EN')[obj.NameTextMapHash])];// obj.EntryPicPath;
|
||||
data.description = language[obj.DescTextMapHash];
|
||||
data.description = sanitizeDescription(language[obj.DescTextMapHash]);
|
||||
|
||||
if(obj.Id === 5120 || obj.Id === 5121 || obj.Id === 5122 || obj.Id === 5123) obj.CityID = 1; // Peak of Vindagnyr region fix from Liyue to Mondstadt
|
||||
data.region = language[xcity.find(city => city.CityId === obj.CityID).CityNameTextMapHash];
|
||||
|
182
myscripts/collateDomainMonsterList.js
Normal file
182
myscripts/collateDomainMonsterList.js
Normal file
@ -0,0 +1,182 @@
|
||||
const fuzzysort = require('fuzzysort');
|
||||
|
||||
const xdungeon = getExcel('DungeonExcelConfigData');
|
||||
|
||||
|
||||
const monsterMap = {
|
||||
"bless autumn hunt i": ['hili berserk', 'el hili grenad', 'ele hili shoot', 'el slime', 'crack axe mita'],
|
||||
"bless autumn hunt ii": ['el hili grenad', 'la el slime', 'mu el slime', 'crack axe mita'],
|
||||
"bless autumn hunt iii": ['la el slime', 'mu el slime', 'el ab mage'],
|
||||
"bless autumn hunt iv": ['la el slime', 'el ab mage', 'thunder lawa'],
|
||||
|
||||
"bless dance steel i": ['treasure ho cr po', 'treasure handy', 'treasure grave', 'treasure sea', 'treasure pug'],
|
||||
"bless dance steel ii": ['fa py agent', 'treasure scout', 'pyro potioneer', 'hydro potioneer', 'handyman', 'pugilist', 'crusher'],
|
||||
"bless dance steel iii": ['pyro agent', 'fa el ci mage', 'th scout', 'th py potion', 'th el potion', 'th handyman', 'th grave', 'th pugilist', 'th crusher'],
|
||||
"bless dance steel iv": ['pyro agent', 'fa el ci mage', 'th pyro pot', 'th hy pot', 'th el pot', 'th cry pot', 'th seaman'],
|
||||
"bless dance steel v": ['pyro agent', 'fa el ci mage', 'th cry pot'],
|
||||
|
||||
"bless elegaic r i": ['cr slime', 'la cry slime', 'ice shield mita'],
|
||||
"bless elegaic r ii": ['cr slime', 'la cr slime', 'cr hili grenad', 'ice shield mita'],
|
||||
"bless elegaic r iii": ['la cr slime', 'cr hili grenad', 'ice shield mita', 'cr ab mage'],
|
||||
"bless elegaic r iv": ['frostarm lawa', 'cr ab mage'],
|
||||
|
||||
"bless fire puri i": ['cryo slime', 'large cryo slime', 'large hydro slime', 'wood shield hili guard', 'cryo mage'],
|
||||
"bless fire puri ii": ['elec slime', 'lar elec slime', 'muta ele slime', 'fat ele cic mage'],
|
||||
"bless fire puri iii": ['cry slime', 'lar cry slime', 'cr ab mage'],
|
||||
"bless fire puri iv": ['hy slime', 'la hy sl', 'hy sama', 'hy ab mage'],
|
||||
"bless fire puri v": ['la cr slime', 'cr ab mage'],
|
||||
"bless fire puri vi": ['la el slime', 'mu el slime', 'fa el ci mage'],
|
||||
|
||||
"bless frost i": ['la el slime', 'mu el slime', 'hy slime', 'la hy slime'],
|
||||
"bless frost ii": ['la py slime', 'bla ax mitachurl', 'py ab mage'],
|
||||
"bless frost iii": ['la el slime', 'mu ele slime', 'hili fighter', 'fa el ci mage'],
|
||||
"bless frost iv": ['la py slime', 'bla axe mitachurl', 'py ab mage'],
|
||||
|
||||
"bless spring i": ['hy slime', 'la hy slime', 'hy ab mage'],
|
||||
"bless spring ii": ['py slime', 'la py slime', 'py ab mage'],
|
||||
"bless spring iii": ['cr slime', 'la cr slime', 'cr ab mage'],
|
||||
"bless spring iv": ['hy slime', 'la hy slime', 'hili fighter', 'hy samachurl', 'hy aby mage'],
|
||||
"bless spring v": ['py ab mage', 'ruin guard'],
|
||||
"bless spring vi": ['hili fighter', 'cr ab mage', 'ruin hunter'],
|
||||
|
||||
"bless stone chamber i": ['py ab mage', 'cr abyss mage'],
|
||||
"bless stone chamber ii": ['py ab mage', 'cr aby mage'],
|
||||
"bless stone chamber iii": ['py ab mage', 'cr ab mage', 'hy ab mage'],
|
||||
|
||||
"bless unyield i": ['py slime', 'la py slime', 'hili berserk'],
|
||||
"bless unyield ii": ['la py slime', 'hili berserk', 'blaz axe mita'],
|
||||
"bless unyield iii": ['la py slime', 'blaz axe mita', 'rock shield mita'],
|
||||
"bless unyield iv": ['geovish'],
|
||||
|
||||
"forge alt sand i": ['hy slime', 'la hy slime', 'py slime', 'la py slime'],
|
||||
"forge alt sand ii": ['la hy slime', 'la py slime'],
|
||||
"forge alt sand iii": ['la hy slime', 'la py slime', 'hy ab mage', 'py ab mage'],
|
||||
"forge alt sand iv": ['el hili grenad', 'la el slime', 'mu el slime', 'crack axe mita'],
|
||||
|
||||
"forge city reflect i": ['hy slime', 'la hy slime'],
|
||||
"forge city reflect ii": ['hy slime', 'la hy slime', 'wood shield hili guard'],
|
||||
"forge city reflect iii": ['hy slime', 'la hy slime', 'hy samachurl', 'hy ab mage'],
|
||||
"forge city reflect iv": ['la hy slime', 'hy ab mage'],
|
||||
|
||||
"forge ruin capital i": ['hy slime', 'la hy slime'],
|
||||
"forge ruin capital ii": ['hy slime', 'la hy slime', 'wood shield hili guard'],
|
||||
"forge ruin capital iii": ['hy slime', 'la hy slime', 'hy samachurl', 'hy ab mage'],
|
||||
"forge ruin capital iv": ['la hy slime', 'hy ab mage'],
|
||||
|
||||
"forge sand burial i": ['hy slime', 'la hy slime', 'py slime', 'la py slime'],
|
||||
"forge sand burial ii": ['la hy slime', 'la py slime'],
|
||||
"forge sand burial iii": ['la hy slime', 'la py slime', 'hy ab mage', 'py ab mage'],
|
||||
"forge sand burial iv": ['el hili grenad', 'la el slime', 'mu el slime', 'crack axe mita'],
|
||||
|
||||
"forge sub valley i": ['hy slime', 'la hy slime'],
|
||||
"forge sub valley ii": ['hy slime', 'la hy slime', 'wood shield hili guard'],
|
||||
"forge sub valley iii": ['hy slime', 'la hy slime', 'hy samachurl', 'hy ab mage'],
|
||||
"forge sub valley iv": ['la hy slime', 'hy ab mage'],
|
||||
|
||||
"forge sunke sand i": ['hy slime', 'la hy slime', 'py slime', 'la py slime'],
|
||||
"forge sunke sand ii": ['la hy slime', 'la py slime'],
|
||||
"forge sunke sand iii": ['la hy slime', 'la py slime', 'hy ab mage', 'py ab mage'],
|
||||
"forge sunke sand iv": ['el hili grenad', 'la el slime', 'mu el slime', 'crack axe mita'],
|
||||
|
||||
"forge thunder alt i": ['el slime', 'la el slime', 'mu el slime'],
|
||||
"forge thunder alt ii": ['el slime', 'la el slime', 'mu el slime'],
|
||||
"forge thunder alt iii": ['la el slime', 'mu el slime', 'fa el ci mage'],
|
||||
"forge thunder alt iv": ['la el slime', 'mu el slime', 'fa el ci mage'],
|
||||
|
||||
"forge thunder ruin i": ['el slime', 'la el slime', 'mu el slime'],
|
||||
"forge thunder ruin ii": ['el slime', 'la el slime', 'mu el slime'],
|
||||
"forge thunder ruin iii": ['la el slime', 'mu el slime', 'fa el ci mage'],
|
||||
"forge thunder ruin iv": ['la el slime', 'mu el slime', 'fa el ci mage'],
|
||||
|
||||
"forge trial thunder i": ['el slime', 'la el slime', 'mu el slime'],
|
||||
"forge trial thunder ii": ['el slime', 'la el slime', 'mu el slime'],
|
||||
"forge trial thunder iii": ['la el slime', 'mu el slime', 'fa el ci mage'],
|
||||
"forge trial thunder iv": ['la el slime', 'mu el slime', 'fa el ci mage'],
|
||||
|
||||
"maste alt flame i": ['py slime', 'la py slime', 'py ab mage'],
|
||||
"maste alt flame ii": ['py slime', 'la py slime', 'py ab mage'],
|
||||
"maste alt flame iii": ['la py slime', 'py ab mage'],
|
||||
"maste alt flame iv": ['blaz axe mita', 'pyro agent'],
|
||||
|
||||
"maste cir ember i": ['py slime', 'la py slime', 'py ab mage'],
|
||||
"maste cir ember ii": ['py slime', 'la py slime', 'py ab mage'],
|
||||
"maste cir ember iii": ['la py slime', 'py ab mage'],
|
||||
"maste cir ember iv": ['blaz axe mita', 'pyro agent'],
|
||||
|
||||
"maste frost alt i": ['cr slime', 'la cr slime', 'cr ab mage'],
|
||||
"maste frost alt ii": ['cr slime', 'la cr slime', 'hili fight', 'cr ab mage'],
|
||||
"maste frost alt iii": ['cr slime', 'la cr slime', 'cr ab mage'],
|
||||
"maste frost alt iv": ['la cr slime', 'cr ab mage'],
|
||||
|
||||
"maste froz abyss i": ['cr slime', 'la cr slime', 'cr ab mage'],
|
||||
"maste froz abyss ii": ['cr slime', 'la cr slime', 'hili fight', 'cr ab mage'],
|
||||
"maste froz abyss iii": ['cr slime', 'la cr slime', 'cr ab mage'],
|
||||
"maste froz abyss iv": ['la cr slime', 'cr ab mage'],
|
||||
|
||||
"maste heart flame i": ['py slime', 'la py slime', 'py ab mage'],
|
||||
"maste heart flame ii": ['py slime', 'la py slime', 'py ab mage'],
|
||||
"maste heart flame iii": ['la py slime', 'py ab mage'],
|
||||
"maste heart flame iv": ['blaz axe mita', 'pyro agent'],
|
||||
|
||||
"maste realm slumb i": ['cr slime', 'la cr slime', 'cr ab mage'],
|
||||
"maste realm slumb ii": ['cr slime', 'la cr slime', 'hili fight', 'cr ab mage'],
|
||||
"maste realm slumb iii": ['cr slime', 'la cr slime', 'cr ab mage'],
|
||||
"maste realm slumb iv": ['la cr slime', 'cr ab mage'],
|
||||
|
||||
"maste reign violet i": ['hili', 'el hili grenad', 'el hili shoot', 'crack axe mita'],
|
||||
"maste reign violet ii": ['nobu jintou', 'nobu hitsuke', 'nobu kikou', 'th pyro pot', 'th elec pot'],
|
||||
"maste reign violet iii": ['nobu hitsuke', 'nobu kikou', 'th pyro pot', 'th el pot', 'kairagi fiery'],
|
||||
"maste reign violet iv": ['th cryo pot', 'kairagi thunder', 'kairagi fiery'],
|
||||
|
||||
"maste thund valley i": ['hili', 'el hili grenad', 'el hili shoot', 'crack axe mita'],
|
||||
"maste thund valley ii": ['nobu jintou', 'nobu hitsuke', 'nobu kikou', 'th pyro pot', 'th elec pot'],
|
||||
"maste thund valley iii": ['nobu hitsuke', 'nobu kikou', 'th pyro pot', 'th el pot', 'kairagi fiery'],
|
||||
"maste thund valley iv": ['th cryo pot', 'kairagi thunder', 'kairagi fiery'],
|
||||
|
||||
"maste vine ruin i": ['hili', 'el hili grenad', 'el hili shoot', 'crack axe mita'],
|
||||
"maste vine ruin ii": ['nobu jintou', 'nobu hitsuke', 'nobu kikou', 'th pyro pot', 'th elec pot'],
|
||||
"maste vine ruin iii": ['nobu hitsuke', 'nobu kikou', 'th pyro pot', 'th el pot', 'kairagi fiery'],
|
||||
"maste vine ruin iv": ['th cryo pot', 'kairagi thunder', 'kairagi fiery'],
|
||||
}
|
||||
|
||||
function autocomplete(input, dict) {
|
||||
let result = fuzzysort.go(input, dict, { limit: 1 })[0];
|
||||
if(result === undefined) console.log('DomainMonsterList: no match found for '+input);
|
||||
return result === undefined ? undefined : result.target;
|
||||
}
|
||||
|
||||
const ENmonster = require('./export/EN/enemies.json');
|
||||
const ENmonsterNames = Object.values(ENmonster).map(ele => ele.name);
|
||||
|
||||
const ENdomain = require('./export/EN/domains.json');
|
||||
const ENdomainNames = Object.values(ENdomain).map(ele => ele.name);
|
||||
|
||||
const autoMonsterMap = {};
|
||||
for(let [dom, monList] of Object.entries(monsterMap)) {
|
||||
dom = autocomplete(dom, ENdomainNames);
|
||||
if(dom === undefined) continue;
|
||||
monList = monList.map(ele => autocomplete(ele, ENmonsterNames));
|
||||
autoMonsterMap[dom] = monList;
|
||||
}
|
||||
|
||||
function collateDomainMonsterList(lang) {
|
||||
const language = getLanguage(lang);
|
||||
let mydomain = require(`./export/${lang}/domains.json`);
|
||||
|
||||
for(let [dom, monList] of Object.entries(autoMonsterMap)) {
|
||||
const domId = Object.values(ENdomain).find(ele => ele.name === dom).Id;
|
||||
const monNameHashList = monList.map(ele => Object.values(ENmonster).find(tmp => tmp.name === ele).NameTextMapHash);
|
||||
|
||||
const monsterlist = monNameHashList.map(NameTextMapHash => language[NameTextMapHash]);
|
||||
|
||||
Object.values(mydomain).find(ele => ele.Id === domId).monsterlist = monsterlist;
|
||||
}
|
||||
|
||||
for(let dom of Object.values(mydomain)) {
|
||||
if(!dom.monsterlist) console.log(dom.name + ' has no monsterlist');
|
||||
}
|
||||
|
||||
return mydomain
|
||||
}
|
||||
|
||||
module.exports = collateDomainMonsterList;
|
@ -41,7 +41,7 @@ function collateEnemy(lang) {
|
||||
data.Id = obj.Id;
|
||||
|
||||
|
||||
|
||||
data.NameTextMapHash = des.NameTextMapHash;
|
||||
data.name = language[des.NameTextMapHash];
|
||||
data.specialname = language[spe.SpecialNameTextMapHash];
|
||||
|
||||
|
@ -40,7 +40,7 @@ function collateMaterial(lang) {
|
||||
data.name = language[obj.NameTextMapHash];
|
||||
if(data.name === '') return accum;
|
||||
data.sortorder = sortOrder;
|
||||
data.description = language[obj.DescTextMapHash];
|
||||
data.description = sanitizeDescription(language[obj.DescTextMapHash]);
|
||||
data.category = obj.MaterialType ? obj.MaterialType.slice(9) : obj.ItemType;
|
||||
data.materialtype = language[obj.TypeDescTextMapHash];
|
||||
if(obj.RankLevel) data.rarity = ''+obj.RankLevel;
|
||||
|
@ -21,7 +21,7 @@ function collateWeapon(lang) {
|
||||
if(accum[filename] !== undefined) console.log(filename+' IS NOT UNIQUE');
|
||||
|
||||
data.name = language[obj.NameTextMapHash];
|
||||
data.description = language[obj.DescTextMapHash];
|
||||
data.description = sanitizeDescription(language[obj.DescTextMapHash]);
|
||||
data.weapontype = language[weaponTextMapHash[obj.WeaponType]];
|
||||
data.rarity = ''+obj.RankLevel;
|
||||
|
||||
@ -42,7 +42,8 @@ function collateWeapon(lang) {
|
||||
if(ref === undefined) break;
|
||||
if(offset === 0) data.effectname = language[ref.NameTextMapHash];
|
||||
let effect = language[ref.DescTextMapHash];
|
||||
if(filename === 'swordofdescension') { // has extra color
|
||||
effect = effect.replace(/<\/color>s/g, 's<\/color>');
|
||||
if(filename === 'swordofdescension' || filename === 'predator') { // has extra color
|
||||
effect = effect.replace(/<color=#.*?>/i, '').replace(/<\/color>/i, '');
|
||||
effect = effect.replace(/<color=#.*?>/i, '').replace(/<\/color>/i, '');
|
||||
}
|
||||
@ -50,14 +51,14 @@ function collateWeapon(lang) {
|
||||
effect = effect.replace(/<color=#.*?>/gi, '{').replace(/<\/color>/gi, '}');
|
||||
effect = effect.split(/{|}/);
|
||||
data['r'+(offset+1)] = [];
|
||||
data['effect'] = effect.reduce((accum, ele, i) => {
|
||||
data['effect'] = sanitizeDescription(effect.reduce((accum, ele, i) => {
|
||||
if(i % 2 === 0) {
|
||||
return accum + ele;
|
||||
} else {
|
||||
data['r'+(offset+1)].push(ele);
|
||||
return accum + `{${(i-1)/2}}`;
|
||||
}
|
||||
}, '');
|
||||
}, ''));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,9 +107,10 @@ function exportData(folder, collateFunc, englishonly, skipwrite) {
|
||||
// exportCurve('weapons', 'WeaponCurveExcelConfigData')
|
||||
// exportData('artifacts', require('./collateArtifact.js'));
|
||||
// exportData('foods', require('./collateFood'));
|
||||
exportData('materials', require('./collateMaterial')); // run twice
|
||||
// exportData('materials', require('./collateMaterial')); // run twice
|
||||
// exportData('domains', require('./collateDomain')); // run twice // remember to add back recommendedelements and disorder and entrypicpath
|
||||
// exportData('enemies', require('./collateEnemy'), true);
|
||||
// exportData('enemies', require('./collateEnemy'));
|
||||
exportData('domains', require('./collateDomainMonsterList')); // run only after both domains and enemies have run. sync
|
||||
|
||||
//console.log(collateCharacter('EN'))
|
||||
//console.log(collateConstellation('EN').hutao)
|
||||
|
29
myscripts/tmp
Normal file
29
myscripts/tmp
Normal file
@ -0,0 +1,29 @@
|
||||
energydrops: [
|
||||
{
|
||||
trigger: {
|
||||
type: "hppercent",
|
||||
value: 66,
|
||||
},
|
||||
particles: [
|
||||
{
|
||||
element: "PYRO",
|
||||
type: "PARTICLE"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
trigger: {
|
||||
type: "kill"
|
||||
},
|
||||
particles: [
|
||||
{
|
||||
element: "COMMON",
|
||||
type: "PARTICLE"
|
||||
},
|
||||
{
|
||||
element: "COMMON",
|
||||
type: "ORB"
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
24
package-lock.json
generated
Normal file
24
package-lock.json
generated
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "GenshinData (3)",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"fuzzysort": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/fuzzysort": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-1.1.4.tgz",
|
||||
"integrity": "sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"fuzzysort": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-1.1.4.tgz",
|
||||
"integrity": "sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ=="
|
||||
}
|
||||
}
|
||||
}
|
5
package.json
Normal file
5
package.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"fuzzysort": "^1.1.4"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user