Merge pull request #190 from unrealkakeman89/character-importer-updates

Character importer updates
This commit is contained in:
CK 2021-04-13 23:14:23 -04:00 committed by GitHub
commit 20f47110cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,52 +1,47 @@
export default class CharacterImporter { export default class CharacterImporter {
// transform JSON from sw5e.com to Foundry friendly format // transform JSON from sw5e.com to Foundry friendly format
// and insert new actor // and insert new actor
static async transform(rawCharacter){ static async transform(rawCharacter) {
const sourceCharacter = JSON.parse(rawCharacter); const sourceCharacter = JSON.parse(rawCharacter); //source character
const details = { const details = {
species: sourceCharacter.attribs.find(e => e.name == "race").current, species: sourceCharacter.attribs.find((e) => e.name == "race").current,
background: sourceCharacter.attribs.find(e => e.name == "background").current, background: sourceCharacter.attribs.find((e) => e.name == "background").current,
alignment: sourceCharacter.attribs.find(e => e.name == "alignment").current alignment: sourceCharacter.attribs.find((e) => e.name == "alignment").current
}
const hp = {
value: sourceCharacter.attribs.find(e => e.name == "hp").current,
min: 0,
max: sourceCharacter.attribs.find(e => e.name == "hp").current,
temp: sourceCharacter.attribs.find(e => e.name == "hp_temp").current
}; };
const ac = { const hp = {
value: sourceCharacter.attribs.find(e => e.name == "ac").current value: sourceCharacter.attribs.find((e) => e.name == "hp").current,
min: 0,
max: sourceCharacter.attribs.find((e) => e.name == "hp").current,
temp: sourceCharacter.attribs.find((e) => e.name == "hp_temp").current
}; };
const abilities = { const abilities = {
str: { str: {
value: sourceCharacter.attribs.find(e => e.name == "strength").current, value: sourceCharacter.attribs.find((e) => e.name == "strength").current,
proficient: sourceCharacter.attribs.find(e => e.name == 'strength_save_prof').current ? 1 : 0 proficient: sourceCharacter.attribs.find((e) => e.name == "strength_save_prof").current ? 1 : 0
}, },
dex: { dex: {
value: sourceCharacter.attribs.find(e => e.name == "dexterity").current, value: sourceCharacter.attribs.find((e) => e.name == "dexterity").current,
proficient: sourceCharacter.attribs.find(e => e.name == 'dexterity_save_prof').current ? 1 : 0 proficient: sourceCharacter.attribs.find((e) => e.name == "dexterity_save_prof").current ? 1 : 0
}, },
con: { con: {
value: sourceCharacter.attribs.find(e => e.name == "constitution").current, value: sourceCharacter.attribs.find((e) => e.name == "constitution").current,
proficient: sourceCharacter.attribs.find(e => e.name == 'constitution_save_prof').current ? 1 : 0 proficient: sourceCharacter.attribs.find((e) => e.name == "constitution_save_prof").current ? 1 : 0
}, },
int: { int: {
value: sourceCharacter.attribs.find(e => e.name == "intelligence").current, value: sourceCharacter.attribs.find((e) => e.name == "intelligence").current,
proficient: sourceCharacter.attribs.find(e => e.name == 'intelligence_save_prof').current ? 1 : 0 proficient: sourceCharacter.attribs.find((e) => e.name == "intelligence_save_prof").current ? 1 : 0
}, },
wis: { wis: {
value: sourceCharacter.attribs.find(e => e.name == "wisdom").current, value: sourceCharacter.attribs.find((e) => e.name == "wisdom").current,
proficient: sourceCharacter.attribs.find(e => e.name == 'wisdom_save_prof').current ? 1 : 0 proficient: sourceCharacter.attribs.find((e) => e.name == "wisdom_save_prof").current ? 1 : 0
}, },
cha: { cha: {
value: sourceCharacter.attribs.find(e => e.name == "charisma").current, value: sourceCharacter.attribs.find((e) => e.name == "charisma").current,
proficient: sourceCharacter.attribs.find(e => e.name == 'charisma_save_prof').current ? 1 : 0 proficient: sourceCharacter.attribs.find((e) => e.name == "charisma_save_prof").current ? 1 : 0
}, }
}; };
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
@ -60,58 +55,58 @@ export default class CharacterImporter {
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
const skills = { const skills = {
acr: { acr: {
value: sourceCharacter.attribs.find(e => e.name == 'acrobatics_type').current value: sourceCharacter.attribs.find((e) => e.name == "acrobatics_type").current
}, },
ani: { ani: {
value: sourceCharacter.attribs.find(e => e.name == 'animal_handling_type').current value: sourceCharacter.attribs.find((e) => e.name == "animal_handling_type").current
}, },
ath: { ath: {
value: sourceCharacter.attribs.find(e => e.name == 'athletics_type').current value: sourceCharacter.attribs.find((e) => e.name == "athletics_type").current
}, },
dec: { dec: {
value: sourceCharacter.attribs.find(e => e.name == 'deception_type').current value: sourceCharacter.attribs.find((e) => e.name == "deception_type").current
}, },
ins: { ins: {
value: sourceCharacter.attribs.find(e => e.name == 'insight_type').current value: sourceCharacter.attribs.find((e) => e.name == "insight_type").current
}, },
inv: { inv: {
value: sourceCharacter.attribs.find(e => e.name == 'investigation_type').current value: sourceCharacter.attribs.find((e) => e.name == "investigation_type").current
}, },
itm: { itm: {
value: sourceCharacter.attribs.find(e => e.name == 'intimidation_type').current value: sourceCharacter.attribs.find((e) => e.name == "intimidation_type").current
}, },
lor: { lor: {
value: sourceCharacter.attribs.find(e => e.name == 'lore_type').current value: sourceCharacter.attribs.find((e) => e.name == "lore_type").current
}, },
med: { med: {
value: sourceCharacter.attribs.find(e => e.name == 'medicine_type').current value: sourceCharacter.attribs.find((e) => e.name == "medicine_type").current
}, },
nat: { nat: {
value: sourceCharacter.attribs.find(e => e.name == 'nature_type').current value: sourceCharacter.attribs.find((e) => e.name == "nature_type").current
}, },
per: { per: {
value: sourceCharacter.attribs.find(e => e.name == 'persuasion_type').current value: sourceCharacter.attribs.find((e) => e.name == "persuasion_type").current
}, },
pil: { pil: {
value: sourceCharacter.attribs.find(e => e.name == 'piloting_type').current value: sourceCharacter.attribs.find((e) => e.name == "piloting_type").current
}, },
prc: { prc: {
value: sourceCharacter.attribs.find(e => e.name == 'perception_type').current value: sourceCharacter.attribs.find((e) => e.name == "perception_type").current
}, },
prf: { prf: {
value: sourceCharacter.attribs.find(e => e.name == 'performance_type').current value: sourceCharacter.attribs.find((e) => e.name == "performance_type").current
}, },
slt: { slt: {
value: sourceCharacter.attribs.find(e => e.name == 'sleight_of_hand_type').current value: sourceCharacter.attribs.find((e) => e.name == "sleight_of_hand_type").current
}, },
ste: { ste: {
value: sourceCharacter.attribs.find(e => e.name == 'stealth_type').current value: sourceCharacter.attribs.find((e) => e.name == "stealth_type").current
}, },
sur: { sur: {
value: sourceCharacter.attribs.find(e => e.name == 'survival_type').current value: sourceCharacter.attribs.find((e) => e.name == "survival_type").current
}, },
tec: { tec: {
value: sourceCharacter.attribs.find(e => e.name == 'technology_type').current value: sourceCharacter.attribs.find((e) => e.name == "technology_type").current
} }
}; };
@ -121,11 +116,10 @@ export default class CharacterImporter {
data: { data: {
abilities: abilities, abilities: abilities,
details: details, details: details,
skills: skills,
attributes: { attributes: {
ac: ac,
hp: hp hp: hp
}, }
skills: skills
} }
}; };
@ -135,98 +129,204 @@ export default class CharacterImporter {
// Parse all classes and add them to already created actor. // Parse all classes and add them to already created actor.
// "class" is a reserved word, therefore I use profession where I can. // "class" is a reserved word, therefore I use profession where I can.
static async addProfessions(sourceCharacter, actor){ static async addProfessions(sourceCharacter, actor) {
let result = []; let result = [];
// parse all class and multiclassX items // parse all class and multiclassX items
// couldn't get Array.filter to work here for some reason // couldn't get Array.filter to work here for some reason
// result = array of objects. each object is a separate class // result = array of objects. each object is a separate class
sourceCharacter.attribs.forEach( (e) => { sourceCharacter.attribs.forEach((e) => {
if ( CharacterImporter.classOrMulticlass(e.name) ){ if (CharacterImporter.classOrMulticlass(e.name)) {
var t = { var t = {
profession: CharacterImporter.capitalize(e.current), profession: CharacterImporter.capitalize(e.current),
type: CharacterImporter.baseOrMulti(e.name), type: CharacterImporter.baseOrMulti(e.name),
level: CharacterImporter.getLevel(e, sourceCharacter) level: CharacterImporter.getLevel(e, sourceCharacter)
} };
result.push(t); result.push(t);
} }
}); });
// pull classes directly from system compendium and add them to current actor // pull classes directly from system compendium and add them to current actor
const professionsPack = await game.packs.get('sw5e.classes').getContent(); const professionsPack = await game.packs.get("sw5e.classes").getContent();
result.forEach( (prof) => { result.forEach((prof) => {
let assignedProfession = professionsPack.find( o => o.name === prof.profession ); let assignedProfession = professionsPack.find((o) => o.name === prof.profession);
assignedProfession.data.data.levels = prof.level; assignedProfession.data.data.levels = prof.level;
actor.createEmbeddedEntity("OwnedItem", assignedProfession.data, { displaySheet: false }); actor.createEmbeddedEntity("OwnedItem", assignedProfession.data, { displaySheet: false });
}); });
this.addSpecies(sourceCharacter.attribs.find((e) => e.name == "race").current, actor);
this.addPowers(
sourceCharacter.attribs.filter((e) => e.name.search(/repeating_power.+_powername/g) != -1).map((e) => e.current),
actor
);
const discoveredItems = sourceCharacter.attribs.filter(
(e) => e.name.search(/repeating_inventory.+_itemname/g) != -1
);
const items = discoveredItems.map((item) => {
const id = item.name.match(/-\w{19}/g);
return {
name: item.current,
quantity: sourceCharacter.attribs.find((e) => e.name === `repeating_inventory_${id}_itemcount`).current
};
});
this.addItems(items, actor);
} }
static classOrMulticlass(name){ static async addClasses(profession, level, actor) {
return name === 'class' || (name.includes('multiclass') && name.length <= 12); let classes = await game.packs.get("sw5e.classes").getContent();
let assignedClass = classes.find((c) => c.name === profession);
assignedClass.data.data.levels = level;
await actor.createEmbeddedEntity("OwnedItem", assignedClass.data, { displaySheet: false });
} }
static baseOrMulti(name){ static classOrMulticlass(name) {
if (name === 'class'){ return name === "class" || (name.includes("multiclass") && name.length <= 12);
return 'base_class'; }
static baseOrMulti(name) {
if (name === "class") {
return "base_class";
} else { } else {
return 'multi_class'; return "multi_class";
} }
} }
static getLevel(item, sourceCharacter){ static getLevel(item, sourceCharacter) {
if (item.name === 'class'){ if (item.name === "class") {
let result = sourceCharacter.attribs.find( e => e.name === 'base_level' ).current; let result = sourceCharacter.attribs.find((e) => e.name === "base_level").current;
return parseInt(result); return parseInt(result);
} else { } else {
let result = sourceCharacter.attribs.find( e => e.name === `${item.name}_lvl` ).current; let result = sourceCharacter.attribs.find((e) => e.name === `${item.name}_lvl`).current;
return parseInt(result); return parseInt(result);
} }
} }
static capitalize(str){ static capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1); return str.charAt(0).toUpperCase() + str.slice(1);
} }
static addImportButton(html){ static async addSpecies(race, actor) {
const species = await game.packs.get("sw5e.species").getContent();
const assignedSpecies = species.find((c) => c.name === race);
const activeEffects = assignedSpecies.data.effects[0].changes;
const actorData = { data: { abilities: { ...actor.data.data.abilities } } };
activeEffects.map((effect) => {
switch (effect.key) {
case "data.abilities.str.value":
actorData.data.abilities.str.value -= effect.value;
break;
case "data.abilities.dex.value":
actorData.data.abilities.dex.value -= effect.value;
break;
case "data.abilities.con.value":
actorData.data.abilities.con.value -= effect.value;
break;
case "data.abilities.int.value":
actorData.data.abilities.int.value -= effect.value;
break;
case "data.abilities.wis.value":
actorData.data.abilities.wis.value -= effect.value;
break;
case "data.abilities.cha.value":
actorData.data.abilities.cha.value -= effect.value;
break;
default:
break;
}
});
actor.update(actorData);
await actor.createEmbeddedEntity("OwnedItem", assignedSpecies.data, { displaySheet: false });
}
static async addPowers(powers, actor) {
const forcePowers = await game.packs.get("sw5e.forcepowers").getContent();
const techPowers = await game.packs.get("sw5e.techpowers").getContent();
for (const power of powers) {
const createdPower = forcePowers.find((c) => c.name === power) || techPowers.find((c) => c.name === power);
if (createdPower) {
await actor.createEmbeddedEntity("OwnedItem", createdPower.data, { displaySheet: false });
}
}
}
static async addItems(items, actor) {
const weapons = await game.packs.get("sw5e.weapons").getContent();
const armors = await game.packs.get("sw5e.armor").getContent();
const adventuringGear = await game.packs.get("sw5e.adventuringgear").getContent();
for (const item of items) {
const createdItem =
weapons.find((c) => c.name.toLowerCase() === item.name.toLowerCase()) ||
armors.find((c) => c.name.toLowerCase() === item.name.toLowerCase()) ||
adventuringGear.find((c) => c.name.toLowerCase() === item.name.toLowerCase());
if (createdItem) {
if (item.quantity != 1) {
createdItem.data.data.quantity = item.quantity;
}
await actor.createEmbeddedEntity("OwnedItem", createdItem.data, { displaySheet: false });
}
}
}
static addImportButton() {
const header = $("#actors").find("header.directory-header"); const header = $("#actors").find("header.directory-header");
const search = $("#actors").children().find("div.header-search"); const search = $("#actors").children().find("div.header-search");
const newImportButtonDiv = $("#actors").children().find("div.header-actions").clone(); const newImportButtonDiv = $("#actors").children().find("div.header-actions").clone();
const newSearch = search.clone(); const newSearch = search.clone();
search.remove(); search.remove();
newImportButtonDiv.attr('id', 'character-sheet-import'); newImportButtonDiv.attr("id", "character-sheet-import");
header.append(newImportButtonDiv); header.append(newImportButtonDiv);
newImportButtonDiv.children("button").remove(); newImportButtonDiv.children("button").remove();
newImportButtonDiv.append("<button class='create-entity' id='cs-import-button'><i class='fas fa-upload'></i> Import Character</button>"); newImportButtonDiv.append(
"<button class='create-entity' id='cs-import-button'><i class='fas fa-upload'></i> Import Character</button>"
);
newSearch.appendTo(header); newSearch.appendTo(header);
let characterImportButton = $("#cs-import-button"); let characterImportButton = $("#cs-import-button");
characterImportButton.click(ev => { characterImportButton.click(() => {
let content = '<h1>Saved Character JSON Import</h1> ' let content =
+ '<label for="character-json">Paste character JSON here:</label> ' "<h1>Saved Character JSON Import</h1> " +
+ '</br>' '<label for="character-json">Paste character JSON here:</label> ' +
+ '<textarea id="character-json" name="character-json" rows="10" cols="50"></textarea>'; "</br>" +
'<textarea id="character-json" name="character-json" rows="10" cols="50"></textarea>';
let importDialog = new Dialog({ let importDialog = new Dialog({
title: "Import Character from SW5e.com", title: "Import Character from SW5e.com",
content: content, content: content,
buttons: { buttons: {
"Import": { Import: {
icon: '<i class="fas fa-file-import"></i>', icon: '<i class="fas fa-file-import"></i>',
label: "Import Character", label: "Import Character",
callback: (e) => { callback: () => {
let characterData = $('#character-json').val(); let characterData = $("#character-json").val();
console.log('Parsing Character JSON'); console.log("Parsing Character JSON");
CharacterImporter.transform(characterData); CharacterImporter.transform(characterData);
} }
}, },
"Cancel": { Cancel: {
icon: '<i class="fas fa-times-circle"></i>', icon: '<i class="fas fa-times-circle"></i>',
label: "Cancel", label: "Cancel",
callback: () => {}, callback: () => {}
} }
} }
}) });
importDialog.render(true); importDialog.render(true);
}); });
} }
} }