UNPKG

parseck2

Version:

Parse a Crusader Kings II saved game file into a usable JavaScript object.

791 lines (742 loc) 23.9 kB
'use strict'; (function () { var allDynasties = require('../data/dynasties.json'); var allTraits = require('../data/traits.json'); var allOpinions = require('../data/opinions.json'); var allAmbitions = require('../data/ambitions.json'); var allNicknames = require('../data/nicknames.json'); var allCultures = require('../data/cultures.json'); var allReligions = require('../data/religions.json'); var allFactions = require('../data/factions.json'); var allSocieties = require('../data/societies.json'); var allArtifacts = require('../data/artifacts.json'); String.prototype.capitalize = function() { return this.charAt(0).toUpperCase() + this.slice(1); } // Derives a Date object from the YYYY.MM.DD formatted // strings used through a Crusader Kings II saved game function getDate(str) { var parts = str.split('.'); var date = undefined; if (parts.length >= 3) { date = new Date(parts[0], (parts[1] - 1), parts[2]); } else if (parts.length == 2) { date = new Date(parts[0], (parts[1] - 1)); } return date; } function getTable(data) { var table = {}; data.forEach(function (datum) { table[datum.id] = datum; }); return table; } function transDynasties(data) { var dynastyTable = {}; var keys = [ "name", "culture", "religion" ]; allDynasties.forEach(function (dynasty) { dynastyTable[dynasty.id] = dynasty; }); data.forEach(function (data) { var dynasty = {}; var isNew = false; if (dynastyTable.hasOwnProperty(data.key)) { dynasty = dynastyTable[data.key]; } else { dynasty.id = data.key; isNew = true; } data.val.forEach(function (pair) { if (keys.indexOf(pair.key) >= 0) { dynasty[pair.key] = pair.val; } }); if (isNew) { allDynasties.push(dynasty); dynastyTable[dynasty.id] = dynasty; } }); return allDynasties; } function transCharacters(data) { var characters = []; data.forEach(function (data) { var character = { id: data.key, spouses: [], titles: [], claims: [], jobs: [], scores: {}, opinions: [], knownPlots: [], factions: { leading: [], member: [], inFavor: [] }, wars: { attacking: [], defending: [] }, treasury: [] }; data.val.forEach(function (pair) { if (pair != null) { if (pair.key == "bn") { character.name = pair.val; } else if (pair.key == "b_d") { var bd = pair.val.split("."); if (bd.length > 2) { character.born = new Date(bd[0], bd[1], bd[2]); } else { character.born = pair.val; } } else if (pair.key == "att") { var attr = pair.val; if (attr.length > 4) { character.attr = { diplomacy: parseInt(attr[0]), martial: parseInt(attr[1]), stewardship: parseInt(attr[2]), intrigue: parseInt(attr[3]), learning: parseInt(attr[4]) }; } } else if (pair.key == "traits") { var traits = []; pair.val.forEach(function (id) { allTraits.forEach(function (trait) { if (trait.id == id) { traits.push(trait); } }); }); character.traits = traits; } else if (pair.key == "claim") { var claim = { pressed: false, weak: false }; pair.val.forEach(function (pair) { if ((pair.key == "title") && (pair.val != undefined) && (pair.val[0].key != undefined) && (pair.val[0].key == "title") && (pair.val[0].val != undefined)) { claim.title = pair.val[0].val; } else if ((pair.key == "pressed") || (pair.key == "weak")) { claim[pair.key] = pair.val; } }); if (claim.title == undefined) { claim = undefined; } character.claims.push(claim); } else if (pair.key == "dnt") { character.dynasty = pair.val; } else if (pair.key == "fat") { character.father = pair.val; } else if (pair.key == "mot") { character.mother = pair.val; } else if (pair.key == "nick") { allNicknames.forEach(function (nick) { if (pair.val == nick.tag) { character.nickname = nick.name; } }); } else if (pair.key == "spouse") { character.spouses.push(pair.val); } else if (pair.key == "cul") { character.culture = pair.val; } else if (pair.key == "rel") { character.religion = pair.val; } else if (pair.key == "fer") { character.fertility = parseFloat(pair.val); } else if (pair.key == "health") { character.health = parseFloat(pair.val); } else if (pair.key == "prs") { character.scores.prestige = parseFloat(pair.val); } else if (pair.key == "piety") { character.scores.piety = parseFloat(pair.val); } else if (pair.key == "wealth") { character.scores.wealth = parseFloat(pair.val); } else if (pair.key == "ambition_date") { character.ambition_date = pair.val; } else if (pair.key == "title") { character.titles.push(pair.val); } else if (pair.key == "job") { character.jobs.push(pair.val); } else if (pair.key == "known_plots") { if (Array.isArray(pair.val)) { pair.val.forEach(function (id) { character.knownPlots.push(id); }); } } } }); characters.push(character); }); return characters; } function transRelations(charTable, data) { data.forEach(function (person) { if ((person.key != undefined) && (person.key.substring(0,4) == "rel_")) { var i = person.key.substring(4); person.val.forEach(function (other) { var u = other.key; other.val.forEach(function (rel) { allOpinions.forEach(function (opinion) { if ((rel.key == opinion.tag) && (charTable[i].opinions != undefined)) { charTable[i].opinions.push({ tag: opinion.tag, description: opinion.description, about: u }); } }); }); }); } }); } function transProvinces(data) { var provinces = []; data.forEach(function(pair) { if (pair != null) { var province = { id: pair.key, modifiers: [], settlements: [] }; pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "name") { province.name = pair.val; } else if (pair.key == "culture") { province.culture = pair.val.capitalize(); } else if (pair.key == "religion") { province.religion = pair.val.capitalize(); } else if (pair.key == "modifier") { pair.val.forEach(function (pair) { if ((pair != null) && (pair.key == "modifier")) { province.modifiers.push(pair.val); } }); } else if (pair.key.substring(0,2) == "b_") { var settlement = { tag: pair.key, name: pair.key.substring(2).capitalize() }; pair.val.forEach(function (pair) { if ((pair != null) && (pair.key == "type")) { settlement.type = pair.val; } }); province.settlements.push(settlement); } } }); provinces.push(province); } }); return provinces; } function transTitles(data) { var titles = []; data.forEach(function (pair) { var title = { tag: pair.key, history: [], laws: [] }; pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "holder") { title.holder = pair.val; } else if (pair.key == "succession") { title.succession = pair.val; } else if (pair.key == "gender") { title.gender = pair.val; } else if (pair.key == "infamy") { pair.val.forEach(function (pair) { if ((pair != null) && (pair.key == "total_infamy")) { title.infamy = pair.val; } }); } else if (pair.key == "liege") { if (Array.isArray(pair.val)) { pair.val.forEach(function (pair) { if ((pair != null) && (pair.key == "title")) { title.liege = pair.val; } }); } else { title.liege = pair.val; } } else if (pair.key == "de_jure_liege") { if (Array.isArray(pair.val)) { pair.val.forEach(function (pair) { if ((pair != null) && (pair.key == "title")) { title.djliege = pair.val; } }); } else { title.djliege = pair.val; } } else if (pair.key == "law") { title.laws.push(pair.val); } else if (pair.key == "history") { pair.val.forEach(function (pair) { if (pair != null) { var event = { date: getDate(pair.key), }; pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "holder") { if (typeof(pair.val) === "string") { event.holder = pair.val; } else { pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "character") { event.holder = pair.val; } else if (pair.key == "type") { event.type = pair.val; } } }); } } } }); title.history.push(event); } }); } } }); titles.push(title); }); return titles; } function transAmbitions(charTable, data) { data.forEach(function (data) { var ambition = undefined; var charID = undefined; data.forEach(function (pair) { if (pair != null) { if (pair.key == "type") { allAmbitions.forEach(function (a) { if (a.tag == pair.val) { ambition = a.name; } }) } else if (pair.key == "scope") { pair.val.forEach(function (pair) { if ((pair != null) && (pair.key == "char")) { charID = pair.val; } }); } } if ((ambition != undefined) && (charID != undefined)) { var a = { description: ambition }; if (charTable[charID].ambition_date != undefined) { a.since = getDate(charTable[charID].ambition_date); } charTable[charID].ambition = a; } }); }); } function transPlots(charTable, data) { data.forEach(function (p) { var plot = { backers: [] }; p.forEach(function (pair) { if (pair != null) { if (pair.key == "type") { plot.type = pair.val; } else if (pair.key == "backer") { plot.backers.push(pair.val); } else if (pair.key == "scope") { if (Array.isArray(pair.val)) { pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "char") { plot.target = pair.val; } else if (pair.key == "from") { if (Array.isArray(pair.val)) { pair.val.forEach(function (pair) { if ((pair != null) && (pair.key == "char")) { plot.by = pair.val; } }); } } } }); } } } }); if (plot.by != undefined) { charTable[plot.by].plot = plot; if (plot.target != undefined) { if (charTable[plot.target] != undefined) { if (charTable[plot.target].plottingAgainst == undefined) { charTable[plot.target].plottingAgainst = []; } charTable[plot.target].plottingAgainst.push(plot.by); } plot.backers.forEach(function (backer) { if (charTable[backer] != undefined) { if (charTable[backer].backing == undefined) { charTable[backer].backing = []; } charTable[backer].backing.push(plot.by); } }); } } }); } function transFaction(data) { var faction = { backers: [] }; data.forEach(function (pair) { if (pair != null) { if (pair.key == "type") { allFactions.forEach(function (f) { if (f.tag == pair.val) { faction.name = f.name; } }); } else if (pair.key == "backer") { faction.backers.push(pair.val); } else if (pair.key == "scope") { pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "title") { if (typeof(pair.val) == "string") { faction.title = pair.val; } else if (Array.isArray(pair.val)) { pair.val.forEach(function (pair) { if ((pair != null) && (pair.key == "title") && (typeof(pair.val) == "string")) { faction.title = pair.val; } }); } } else if (pair.key == "new_char") { faction.claimant = pair.val; } else if (pair.key == "from") { pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "char") { faction.leader = pair.val; } } }); } } }); } } }); return faction; } function transWar(data) { var war = {}; var attackers = []; var attackersJoined = []; var defenders = []; var defendersJoined = []; var a = []; var d = []; data.forEach(function (pair) { if (pair.key == "name") { war.name = pair.val; } else if (pair.key == "attacker") { attackers.push(pair.val); } else if (pair.key == "defender") { defenders.push(pair.val); } else if (pair.key == "attacker_dates") { attackersJoined.push(getDate(pair.val)); } else if (pair.key == "defender_dates") { defendersJoined.push(getDate(pair.val)); } }); for (var i = 0; i < Math.min(attackers.length, attackersJoined.length); i++) { a.push({ character: attackers[i], joined: attackersJoined[i] }); } for (i = 0; i < Math.min(defenders.length, defendersJoined.length); i++) { d.push({ character: defenders[i], joined: defendersJoined[i] }); } war.attackers = a; war.defenders = d; return war; } function transSocieties(data) { var societies = []; data.forEach(function (pair) { if (pair != null) { var society = { members: {} }; pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "type") { allSocieties.forEach(function (societyData) { if (societyData.tag == pair.val) { Object.assign(society, societyData); } }); } else if (pair.key == "society_leader") { society.leader = pair.val; } else if (pair.key == "member") { var memberData = {}; pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "character") { memberData.id = pair.val; } else if (pair.key == "society_rank") { memberData.rank = pair.val; } else if (pair.key == "society_currency") { memberData.currency = pair.val; } else if (pair.key == "days_in_society") { memberData.daysInSociety = pair.val; } else if (pair.key == "days_at_current_society_rank") { memberData.daysAtRank = pair.val; } } }); society.members[memberData.id] = { rank: memberData.rank, currency: memberData.currency, daysInSociety: memberData.daysInSociety, daysAtRank: memberData.daysAtRank }; } } }); if ((society.leader != undefined) && (society.members[society.leader] != undefined)) { society.members[society.leader].leader = true; } societies.push(society); } }); return societies; } function transArtifacts(data) { var artifacts = {}; data.forEach(function (pair) { if (pair != null) { var artifact = { flags: [] }; pair.val.forEach(function (pair) { if (pair != null) { if (pair.key == "type") { allArtifacts.forEach(function (artifactData) { if (artifactData.tag == pair.val) { Object.assign(artifact, artifactData); } }); } else if (pair.key == "owner") { artifact.owner = pair.val; } else if (pair.key == "org_owner") { artifact.originalOwner = pair.val; } else if (pair.key == "obtained") { artifact.obtained = getDate(pair.val); } else if (pair.key == "active") { artifact.active = pair.val; } else if (pair.key == "flags") { var memberData = {}; pair.val.forEach(function (pair) { if (pair != null) { artifact.flags.push({ flag: pair.key, date: getDate(pair.val) }); } }); } } }); if (artifact.tag != undefined) { artifacts[artifact.tag] = artifact; } } }); return artifacts; } function removeAmbitionDates(characters) { characters.forEach(function (character) { if (character["ambition_date"] != undefined) { delete character["ambition_date"]; } }); } function compileCultureReligion(characters, dynasties) { characters.forEach(function (character) { if ((character.hasOwnProperty("dynasty")) && (dynasties.hasOwnProperty(character.dynasty))) { var dynasty = dynasties[character.dynasty]; if (!character.hasOwnProperty("culture")) { character.culture = dynasty.culture; } if (!character.hasOwnProperty("religion")) { character.religion = dynasty.religion; } } }); } function parseNicknames(characters) { characters.forEach(function (character) { var culture = undefined; var religion = undefined; allCultures.forEach(function (c) { if (c.tag == character.culture) { culture = c; } }); allReligions.forEach(function (r) { if (r.tag == character.religion) { religion = r; } }); if ((character.nickname != undefined) && (culture != undefined)) { character.nickname = character.nickname.replace('$CULTURE_SINGULAR', culture.individual); character.nickname = character.nickname.replace('$CULTURE_PLURAL', culture.plural); } if ((character.nickname != undefined) && (religion != undefined)) { character.nickname = character.nickname.replace('$RELIGION_SINGULAR', religion.individual); character.nickname = character.nickname.replace('$GOD', religion.god); character.nickname = character.nickname.replace('$DEVIL', religion.devil); } }); } function parseFactions(factions, charTable) { factions.forEach(function (faction, index) { if (faction.title != undefined) { faction.name = faction.name.replace('$TITLE', faction.title.substring(2).capitalize()); } if ((faction.claimant != undefined) && (charTable[faction.claimant] != undefined)) { charTable[faction.claimant].factions.inFavor.push(index); faction.name = faction.name.replace('$CLAIMANT', charTable[faction.claimant].name); } if ((faction.leader != undefined) && (charTable[faction.leader] != undefined)) { charTable[faction.leader].factions.leading.push(index); } faction.backers.forEach(function (backer) { if (charTable[backer] != undefined) { charTable[backer].factions.member.push(index); } }); }); } function connectWars(wars, charTable) { wars.forEach(function (war, index) { war.attackers.forEach(function (attacker) { if (charTable[attacker.character] != undefined) { charTable[attacker.character].wars.attacking.push({ war: war.name, index: index, joined: attacker.joined }); } }); war.defenders.forEach(function (defender) { if (charTable[defender.character] != undefined) { charTable[defender.character].wars.defending.push({ war: war.name, index: index, joined: defender.joined }); } }); }); } function connectSocieties(societies, charTable) { societies.forEach(function (society) { Object.keys(society.members).forEach(function (member) { if (charTable[member] != undefined) { charTable[member].society = society.tag; } }); }); } function connectArtifacts(artifacts, charTable) { Object.keys(artifacts).forEach(function (tag) { var ownerID = artifacts[tag].owner; if (charTable[ownerID] != undefined) { charTable[ownerID].treasury.push(tag); } }); } var transform = function (parsed) { var obj = { dynasties: [], characters: [], provinces: [], titles: [], factions: [], wars: [], societies: [], artifacts: [] }; var second = { relations: [], ambitions: [], plots: [] }; parsed.forEach(function (pair) { if (pair != null) { if (pair.key == "dynasties") { obj.dynasties = transDynasties(pair.val); } else if (pair.key == "character") { obj.characters = transCharacters(pair.val); } else if (pair.key == "relation") { second.relations = pair.val; } else if (pair.key == "provinces") { obj.provinces = transProvinces(pair.val); } else if (pair.key == "title") { obj.titles = transTitles(pair.val); } else if (pair.key == "active_ambition") { second.ambitions.push(pair.val); } else if (pair.key == "active_plot") { second.plots.push(pair.val); } else if (pair.key == "active_faction") { obj.factions.push(transFaction(pair.val)); } else if (pair.key == "active_war") { obj.wars.push(transWar(pair.val)); } else if (pair.key == "society") { obj.societies = transSocieties(pair.val); } else if (pair.key == "artifacts") { obj.artifacts = transArtifacts(pair.val); } } }); var charTable = getTable(obj.characters); var dynastyTable = getTable(obj.dynasties); transRelations(charTable, second.relations); transAmbitions(charTable, second.ambitions); removeAmbitionDates(obj.characters); transPlots(charTable, second.plots); compileCultureReligion(obj.characters, dynastyTable); parseNicknames(obj.characters); parseFactions(obj.factions, charTable); connectWars(obj.wars, charTable); connectSocieties(obj.societies, charTable); connectArtifacts(obj.artifacts, charTable); return obj; }; module.exports = transform; })();