UNPKG

megaten

Version:

An unofficial collection of data from the Shin Megami Tensei and Persona games.

151 lines (150 loc) 5.81 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Persona = exports.Demon = void 0; const node_fs_1 = require("node:fs"); const promises_1 = require("node:fs/promises"); const node_path_1 = __importDefault(require("node:path")); const util_1 = require("@squiddleton/util"); const demonData_js_1 = __importDefault(require("./demonData.js")); const error_js_1 = require("./error.js"); const skill_js_1 = require("./skill.js"); function isPersona(demon) { return demon.race === 'Persona'; } function mapByDevName(obj) { return [obj.devName, obj]; } class Demon { /** The demon's name */ name; /** The demon's alternative names */ aliases; /** The demon's normalized name used for matching queries */ devName; /** The demon's skill potential and inherit affinity */ affinities; /** The demon's Arcana in Persona titles, or null if unknown */ arcana; /** The demon's race in mainline Shin Megami Tensei titles, or null if unknown */ race; /** The demon's initial level */ level; /** The demon's initial HP */ hp; /** The demon's initial MP/SP */ mp; /** The demon's initial stats */ stats; /** The skills that the demon learns via leveling up */ learnset; /** The demon's ailment and affinity resistances */ resistances; /** The game that the demon's data originates from */ game; /** The demon's moral and ethical alignment */ alignment; /** The demon's backstory, or null for older Personas */ lore; /** The demon's mythological origin */ origin; constructor(data) { this.name = data.name; this.aliases = data.aliases ?? []; this.devName = (0, util_1.normalize)(data.name); this.affinities = data.affinities; this.arcana = data.arcana; this.race = data.race; this.level = data.level; this.hp = data.hp; this.mp = data.mp; this.stats = data.stats; this.learnset = data.learnset; this.resistances = data.resistances; this.game = data.game; this.alignment = data.alignment; this.lore = data.lore; this.origin = data.origin; } /** Asynchronously gets an image of the demon */ getImage() { return (0, promises_1.readFile)(node_path_1.default.join(__dirname, '..', `images/demons/${this.devName}.png`)); } /** Whether the demon is a Persona instance */ isPersona() { return isPersona(this); } /** Whether the demon is exclusive to Persona games */ isPersonaBased() { return this.race !== null && ['Persona', 'Picaro', 'Treasure'].includes(this.race); } /** Returns a string in "(Race) (Name)" format, or the name if the race is unknown */ toString() { return this.race !== null && !this.isPersonaBased() ? `${this.race} ${this.name}` : this.name; } /** An image of the demon */ get image() { return (0, node_fs_1.readFileSync)(node_path_1.default.join(__dirname, '..', `images/demons/${this.devName}.png`)); } /** An array of every Demon and Persona instance */ static array = []; /** A map of every Demon and Persona instance, keyed by their devName properties */ static map = new Map(); static get(name, error = false) { const normalized = (0, util_1.normalize)(name); const found = this.map.get(normalized) ?? this.array.find(demon => demon.aliases.some(alias => (0, util_1.normalize)(alias) === normalized)) ?? null; if (error && found === null) throw new error_js_1.MegatenError(name, 'Demon'); return found; } } exports.Demon = Demon; class Persona extends Demon { /** The Persona's user */ user; /** The Persona's stage of evolution */ stage; /** The name of the skill that the Persona will learn upon reaching this stage, or null if none */ evoSkillName; /** The Skill instance that the Persona will learn upon reaching this stage, or null if none */ evoSkill; constructor(data) { super(data); this.user = data.user; this.stage = data.stage; this.evoSkillName = data.evoSkillName; this.evoSkill = this.evoSkillName === null ? null : skill_js_1.Skill.get(this.evoSkillName, true); } /** The Persona that this Persona can evolve into, or null if none */ get evolution() { return Persona.array.find(persona => persona.user === this.user && persona.stage === (this.stage + 1)) ?? null; } /** * Returns a string in "(User)'s (Name)" format */ toString() { return `${(0, util_1.formatPossessive)(this.user)} ${this.name}`; } /** An array of every Persona instance */ static array = []; /** A map of every Persona instance, keyed by their devName properties */ static map = new Map(); static get(name, error = false) { try { return super.get(name, error); } catch (e) { if (e instanceof error_js_1.MegatenError) throw new error_js_1.MegatenError(name, 'Persona'); else throw e; } } } exports.Persona = Persona; Demon.array = Object.freeze(demonData_js_1.default.map(data => isPersona(data) ? new Persona(data) : new Demon(data))); Demon.map = new Map(Demon.array.map(mapByDevName)); Persona.array = Object.freeze(Demon.array.filter(isPersona)); Persona.map = new Map(Persona.array.map(mapByDevName));