Ajout de la commande /gennpc pour générer des PNJ Traveller
Implémentation complète du générateur de PNJ Traveller basé sur : https://github.com/carloscasalar/traveller-npc-generator Fonctionnalités : - Génération de caractéristiques selon 4 catégories de citoyens - Distribution des compétences selon 6 niveaux d'expérience - 14 rôles différents avec priorités de caractéristiques spécifiques - Génération de noms aléatoires (masculin/féminin/neutre) - Création de fiche d'acteur mgt2e avec toutes les compétences - Interface utilisateur avec dialogue Handlebars - Commande /gennpc dans le chat Fichiers ajoutés : - scripts/data/travellerNpcGenerator.js (données et constantes) - scripts/travellerNpcGenerator.js (logique métier) - scripts/TravellerNpcDialog.js (interface utilisateur) - templates/traveller-npc-dialog.hbs (template dialogue) - templates/traveller-npc-result.hbs (template résultat) - styles/traveller-npc.css (styles spécifiques) Fichiers modifiés : - scripts/npc.js (intégration de la commande) - module.json (ajout des nouveaux scripts et styles) Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
@@ -0,0 +1,715 @@
|
||||
/**
|
||||
* Traveller NPC Generator - Données de configuration
|
||||
* Basé sur : https://github.com/carloscasalar/traveller-npc-generator
|
||||
*
|
||||
* Ce fichier contient toutes les données nécessaires pour générer des PNJ
|
||||
* selon les règles du générateur Traveller.
|
||||
*/
|
||||
|
||||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||||
|
||||
// ============================================================================
|
||||
// Catégories de citoyens
|
||||
// ============================================================================
|
||||
|
||||
export const CITIZEN_CATEGORY = {
|
||||
BELOW_AVERAGE: {
|
||||
key: 'belowAverage',
|
||||
label: 'En dessous de la moyenne',
|
||||
value: 0,
|
||||
characteristicArray: [8, 7, 6, 6, 5, 4],
|
||||
description: 'Citoyen avec des capacités inférieures à la moyenne'
|
||||
},
|
||||
AVERAGE: {
|
||||
key: 'average',
|
||||
label: 'Moyenne',
|
||||
value: 1,
|
||||
characteristicArray: [9, 8, 7, 7, 6, 5],
|
||||
description: 'Citoyen moyen'
|
||||
},
|
||||
ABOVE_AVERAGE: {
|
||||
key: 'aboveAverage',
|
||||
label: 'Au-dessus de la moyenne',
|
||||
value: 2,
|
||||
characteristicArray: [10, 9, 8, 8, 7, 6],
|
||||
description: 'Citoyen avec des capacités supérieures à la moyenne'
|
||||
},
|
||||
EXCEPTIONAL: {
|
||||
key: 'exceptional',
|
||||
label: 'Exceptionnel',
|
||||
value: 3,
|
||||
characteristicArray: [11, 10, 9, 9, 8, 7],
|
||||
description: 'Citoyen exceptionnel'
|
||||
}
|
||||
};
|
||||
|
||||
export const CITIZEN_CATEGORY_LIST = [
|
||||
CITIZEN_CATEGORY.BELOW_AVERAGE,
|
||||
CITIZEN_CATEGORY.AVERAGE,
|
||||
CITIZEN_CATEGORY.ABOVE_AVERAGE,
|
||||
CITIZEN_CATEGORY.EXCEPTIONAL
|
||||
];
|
||||
|
||||
// ============================================================================
|
||||
// Niveaux d'expérience
|
||||
// ============================================================================
|
||||
|
||||
export const EXPERIENCE_LEVEL = {
|
||||
RECRUIT: {
|
||||
key: 'recruit',
|
||||
label: 'Recrue',
|
||||
value: 0,
|
||||
skillDistribution: {
|
||||
level0: 4,
|
||||
level1: 0,
|
||||
level2: 0,
|
||||
level3: 0
|
||||
},
|
||||
description: 'Nouveau, sans expérience'
|
||||
},
|
||||
ROOKIE: {
|
||||
key: 'rookie',
|
||||
label: 'Débutant',
|
||||
value: 1,
|
||||
skillDistribution: {
|
||||
level0: 4,
|
||||
level1: 2,
|
||||
level2: 0,
|
||||
level3: 0
|
||||
},
|
||||
description: 'Débutant avec un peu d\'expérience'
|
||||
},
|
||||
INTERMEDIATE: {
|
||||
key: 'intermediate',
|
||||
label: 'Intermédiaire',
|
||||
value: 2,
|
||||
skillDistribution: {
|
||||
level0: 4,
|
||||
level1: 2,
|
||||
level2: 1,
|
||||
level3: 0
|
||||
},
|
||||
description: 'Niveau intermédiaire'
|
||||
},
|
||||
REGULAR: {
|
||||
key: 'regular',
|
||||
label: 'Régulier',
|
||||
value: 3,
|
||||
skillDistribution: {
|
||||
level0: 5,
|
||||
level1: 2,
|
||||
level2: 2,
|
||||
level3: 0
|
||||
},
|
||||
description: 'Expérience régulière'
|
||||
},
|
||||
VETERAN: {
|
||||
key: 'veteran',
|
||||
label: 'Vétéran',
|
||||
value: 4,
|
||||
skillDistribution: {
|
||||
level0: 5,
|
||||
level1: 2,
|
||||
level2: 3,
|
||||
level3: 0
|
||||
},
|
||||
description: 'Vétéran expérimenté'
|
||||
},
|
||||
ELITE: {
|
||||
key: 'elite',
|
||||
label: 'Élite',
|
||||
value: 5,
|
||||
skillDistribution: {
|
||||
level0: 6,
|
||||
level1: 3,
|
||||
level2: 2,
|
||||
level3: 1
|
||||
},
|
||||
description: 'Élite, très expérimenté'
|
||||
}
|
||||
};
|
||||
|
||||
export const EXPERIENCE_LEVEL_LIST = [
|
||||
EXPERIENCE_LEVEL.RECRUIT,
|
||||
EXPERIENCE_LEVEL.ROOKIE,
|
||||
EXPERIENCE_LEVEL.INTERMEDIATE,
|
||||
EXPERIENCE_LEVEL.REGULAR,
|
||||
EXPERIENCE_LEVEL.VETERAN,
|
||||
EXPERIENCE_LEVEL.ELITE
|
||||
];
|
||||
|
||||
// ============================================================================
|
||||
// Rôles (Crew roles in a starship)
|
||||
// ============================================================================
|
||||
|
||||
// Caractéristiques par rôle - définit quelles caractéristiques sont prioritaires
|
||||
// pour chaque rôle (High, Medium, Low)
|
||||
export const CHARACTERISTIC_PRIORITIES = {
|
||||
pilot: {
|
||||
high: ['DEX', 'INT'],
|
||||
medium: ['EDU', 'STR'],
|
||||
low: ['END', 'SOC']
|
||||
},
|
||||
navigator: {
|
||||
high: ['INT', 'EDU'],
|
||||
medium: ['DEX', 'SOC'],
|
||||
low: ['STR', 'END']
|
||||
},
|
||||
engineer: {
|
||||
high: ['INT', 'EDU'],
|
||||
medium: ['DEX', 'END'],
|
||||
low: ['STR', 'SOC']
|
||||
},
|
||||
steward: {
|
||||
high: ['INT', 'SOC'],
|
||||
medium: ['DEX', 'EDU'],
|
||||
low: ['STR', 'END']
|
||||
},
|
||||
medic: {
|
||||
high: ['INT', 'EDU'],
|
||||
medium: ['DEX', 'SOC'],
|
||||
low: ['STR', 'END']
|
||||
},
|
||||
marine: {
|
||||
high: ['STR', 'END'],
|
||||
medium: ['DEX', 'INT'],
|
||||
low: ['EDU', 'SOC']
|
||||
},
|
||||
gunner: {
|
||||
high: ['DEX', 'INT'],
|
||||
medium: ['END', 'EDU'],
|
||||
low: ['STR', 'SOC']
|
||||
},
|
||||
scout: {
|
||||
high: ['DEX', 'INT'],
|
||||
medium: ['END', 'EDU'],
|
||||
low: ['STR', 'SOC']
|
||||
},
|
||||
technician: {
|
||||
high: ['INT', 'EDU'],
|
||||
medium: ['DEX', 'END'],
|
||||
low: ['STR', 'SOC']
|
||||
},
|
||||
leader: {
|
||||
high: ['INT', 'SOC'],
|
||||
medium: ['EDU', 'END'],
|
||||
low: ['DEX', 'STR']
|
||||
},
|
||||
diplomat: {
|
||||
high: ['INT', 'SOC'],
|
||||
medium: ['EDU', 'DEX'],
|
||||
low: ['STR', 'END']
|
||||
},
|
||||
entertainer: {
|
||||
high: ['DEX', 'SOC'],
|
||||
medium: ['INT', 'EDU'],
|
||||
low: ['STR', 'END']
|
||||
},
|
||||
trader: {
|
||||
high: ['INT', 'SOC'],
|
||||
medium: ['EDU', 'DEX'],
|
||||
low: ['STR', 'END']
|
||||
},
|
||||
thug: {
|
||||
high: ['STR', 'END'],
|
||||
medium: ['DEX', 'INT'],
|
||||
low: ['EDU', 'SOC']
|
||||
}
|
||||
};
|
||||
|
||||
// Compétences pertinentes pour chaque rôle
|
||||
export const ROLE_SKILLS = {
|
||||
pilot: [
|
||||
'Pilot-Spacecraft',
|
||||
'Astrogation',
|
||||
'Electronics-Sensors',
|
||||
'Gunner',
|
||||
'Mechanic',
|
||||
'Pilot-Small Craft',
|
||||
'Leadership',
|
||||
'Vacc Suit',
|
||||
'Communications',
|
||||
'Drive-Grav',
|
||||
'Survival',
|
||||
'Recon',
|
||||
'Flyer'
|
||||
],
|
||||
navigator: [
|
||||
'Astrogation',
|
||||
'Electronics-Sensors',
|
||||
'Pilot-Spacecraft',
|
||||
'Computers',
|
||||
'Survival',
|
||||
'Navigation',
|
||||
'Mechanic',
|
||||
'Leadership',
|
||||
'Tactics',
|
||||
'Engineer',
|
||||
'Vacc Suit',
|
||||
'Recon'
|
||||
],
|
||||
engineer: [
|
||||
'Engineer-MDrive',
|
||||
'Mechanic',
|
||||
'Engineer-Power',
|
||||
'Computers',
|
||||
'Engineer-JDrive',
|
||||
'Engineer-Life Support',
|
||||
'Electronics-Sensors',
|
||||
'Survival',
|
||||
'Pilot-Small Craft',
|
||||
'Leadership',
|
||||
'Vacc Suit',
|
||||
'Recon',
|
||||
'Drive'
|
||||
],
|
||||
steward: [
|
||||
'Steward',
|
||||
'Carouse',
|
||||
'Persuade',
|
||||
'Broker',
|
||||
'Admin',
|
||||
'Computers',
|
||||
'Language',
|
||||
'Advocate',
|
||||
'Leadership',
|
||||
'Medic',
|
||||
'Streetwise',
|
||||
'Diplomat'
|
||||
],
|
||||
medic: [
|
||||
'Medic',
|
||||
'Science-Biology',
|
||||
'Science-Chemistry',
|
||||
'Deception',
|
||||
'Investigate',
|
||||
'Diplomat',
|
||||
'Computers',
|
||||
'Persuade',
|
||||
'Admin',
|
||||
'Broker',
|
||||
'Electronics-Sensors',
|
||||
'Drive',
|
||||
'Leadership'
|
||||
],
|
||||
marine: [
|
||||
'Gun Combat',
|
||||
'Survival',
|
||||
'Athletics-Strength',
|
||||
'Melee-Unarmed',
|
||||
'Heavy Weapons',
|
||||
'Tactics',
|
||||
'Recon',
|
||||
'Electronics-Sensors',
|
||||
'Leadership',
|
||||
'Medic',
|
||||
'Drive-Grav',
|
||||
'Communications',
|
||||
'Stealth'
|
||||
],
|
||||
gunner: [
|
||||
'Gunner-Turrets',
|
||||
'Electronics-Sensors',
|
||||
'Gunner-Screens',
|
||||
'Tactics',
|
||||
'Gun Combat',
|
||||
'Leadership',
|
||||
'Mechanic',
|
||||
'Heavy Weapons',
|
||||
'Explosives',
|
||||
'Computers',
|
||||
'Pilot-Small Craft',
|
||||
'Athletics-Dexterity',
|
||||
'Melee-Blade'
|
||||
],
|
||||
scout: [
|
||||
'Survival',
|
||||
'Recon',
|
||||
'Pilot-Small Craft',
|
||||
'Astrogation',
|
||||
'Electronics-Sensors',
|
||||
'Stealth',
|
||||
'Gunner',
|
||||
'Medic',
|
||||
'Tactics',
|
||||
'Gun Combat',
|
||||
'Navigation',
|
||||
'Leadership'
|
||||
],
|
||||
technician: [
|
||||
'Mechanic',
|
||||
'Computers',
|
||||
'Electronics-Sensors',
|
||||
'Engineer-Power',
|
||||
'Engineer-MDrive',
|
||||
'Drive',
|
||||
'Pilot',
|
||||
'Vacc Suit',
|
||||
'Recon',
|
||||
'Athletics-Dexterity',
|
||||
'Survival',
|
||||
'Explosives'
|
||||
],
|
||||
leader: [
|
||||
'Leadership',
|
||||
'Tactics',
|
||||
'Admin',
|
||||
'Diplomat',
|
||||
'Persuade',
|
||||
'Advocate',
|
||||
'Electronics-Sensors',
|
||||
'Computers',
|
||||
'Deception',
|
||||
'Pilot-Spacecraft',
|
||||
'Engineer',
|
||||
'Recon',
|
||||
'Medic'
|
||||
],
|
||||
diplomat: [
|
||||
'Diplomat',
|
||||
'Persuade',
|
||||
'Advocate',
|
||||
'Admin',
|
||||
'Carouse',
|
||||
'Steward',
|
||||
'Streetwise',
|
||||
'Language',
|
||||
'Broker',
|
||||
'Leadership',
|
||||
'Communications',
|
||||
'Tactics'
|
||||
],
|
||||
entertainer: [
|
||||
'Carouse',
|
||||
'Streetwise',
|
||||
'Art-Instrument',
|
||||
'Persuade',
|
||||
'Stealth',
|
||||
'Deception',
|
||||
'Diplomat',
|
||||
'Art-Acting',
|
||||
'Computers',
|
||||
'Electronics-Sensors',
|
||||
'Leadership',
|
||||
'Broker',
|
||||
'Melee-Blade',
|
||||
'Admin'
|
||||
],
|
||||
trader: [
|
||||
'Broker',
|
||||
'Persuade',
|
||||
'Admin',
|
||||
'Advocate',
|
||||
'Computers',
|
||||
'Streetwise',
|
||||
'Gun Combat',
|
||||
'Diplomat',
|
||||
'Deception',
|
||||
'Carouse',
|
||||
'Communications',
|
||||
'Mechanic',
|
||||
'Electronics-Sensors',
|
||||
'Leadership'
|
||||
],
|
||||
thug: [
|
||||
'Melee-Unarmed',
|
||||
'Gun Combat',
|
||||
'Melee-Blade',
|
||||
'Athletics-Strength',
|
||||
'Stealth',
|
||||
'Streetwise',
|
||||
'Carouse',
|
||||
'Tactics',
|
||||
'Stealth',
|
||||
'Survival',
|
||||
'Persuade',
|
||||
'Explosives',
|
||||
'Computers'
|
||||
]
|
||||
};
|
||||
|
||||
// Liste des rôles avec libellés en français
|
||||
export const ROLE = {
|
||||
PILOT: { key: 'pilot', label: 'Pilote', description: 'Pilote de vaisseau spatial' },
|
||||
NAVIGATOR: { key: 'navigator', label: 'Navigateur', description: 'Navigateur spatial' },
|
||||
ENGINEER: { key: 'engineer', label: 'Ingénieur', description: 'Ingénieur de bord' },
|
||||
STEWARD: { key: 'steward', label: 'Intendant', description: 'Intendant / steward' },
|
||||
MEDIC: { key: 'medic', label: 'Médecin', description: 'Médecin de bord' },
|
||||
MARINE: { key: 'marine', label: 'Marine', description: 'Marine / soldat' },
|
||||
GUNNER: { key: 'gunner', label: 'Artilleur', description: 'Artilleur / canonnier' },
|
||||
SCOUT: { key: 'scout', label: 'Éclaireur', description: 'Éclaireur' },
|
||||
TECHNICIAN: { key: 'technician', label: 'Technicien', description: 'Technicien' },
|
||||
LEADER: { key: 'leader', label: 'Chef', description: 'Chef / leader' },
|
||||
DIPLOMAT: { key: 'diplomat', label: 'Diplomate', description: 'Diplomate' },
|
||||
ENTERTAINER: { key: 'entertainer', label: 'Artiste', description: 'Artiste / divertisseur' },
|
||||
TRADER: { key: 'trader', label: 'Marchand', description: 'Marchand / commerçant' },
|
||||
THUG: { key: 'thug', label: 'Brute', description: 'Brute / voyou' }
|
||||
};
|
||||
|
||||
export const ROLE_LIST = [
|
||||
ROLE.PILOT,
|
||||
ROLE.NAVIGATOR,
|
||||
ROLE.ENGINEER,
|
||||
ROLE.STEWARD,
|
||||
ROLE.MEDIC,
|
||||
ROLE.MARINE,
|
||||
ROLE.GUNNER,
|
||||
ROLE.SCOUT,
|
||||
ROLE.TECHNICIAN,
|
||||
ROLE.LEADER,
|
||||
ROLE.DIPLOMAT,
|
||||
ROLE.ENTERTAINER,
|
||||
ROLE.TRADER,
|
||||
ROLE.THUG
|
||||
];
|
||||
|
||||
// ============================================================================
|
||||
// Genre
|
||||
// ============================================================================
|
||||
|
||||
export const GENDER = {
|
||||
UNSPECIFIED: { key: 'unspecified', label: 'Non spécifié', value: 0 },
|
||||
FEMALE: { key: 'female', label: 'Féminin', value: 1 },
|
||||
MALE: { key: 'male', label: 'Masculin', value: 2 }
|
||||
};
|
||||
|
||||
export const GENDER_LIST = [
|
||||
GENDER.UNSPECIFIED,
|
||||
GENDER.FEMALE,
|
||||
GENDER.MALE
|
||||
];
|
||||
|
||||
// ============================================================================
|
||||
// Catalogues de noms
|
||||
// ============================================================================
|
||||
|
||||
export const NAME_CATALOGS = {
|
||||
surnames: [
|
||||
'Anderson', 'Berezovsky', 'Brown', 'Chen', 'Clark', 'Davis', 'Fujita', 'Garcia',
|
||||
'Gupta', 'Harris', 'Hicks', 'Ito', 'Ivanov', 'Jackson', 'Johnson', 'Jones',
|
||||
'Kim', 'Kobayashi', 'Kowalski', 'Kumar', 'Kuznetsoff', 'Kuznetsov', 'Kuznetsova',
|
||||
'Lee', 'Martin', 'Martinez', 'Miller', 'Moore', 'Nakamura', 'Nguyen', 'Nowak',
|
||||
"O'Brien", "O'Callaghan", "O'Connell", "O'Connor", "O'Keefe", "O'Leary",
|
||||
"O'Malley", "O'Neil", "O'Reilly", "O'Sullivan", 'Park', 'Patel', 'Pierzynski',
|
||||
'Pietrzykowski', 'Pisarski', 'Reshevsky', 'Robinson', 'Rumkowska', 'Saito',
|
||||
'Singh', 'Smith', 'Tanaka', 'Taylor', 'Thomas', 'Thompson', 'Vasquez',
|
||||
'Watanabe', 'White', 'Williams', 'Wilson', 'Wong', 'Yamamoto', 'Yang'
|
||||
],
|
||||
nonGenderedNames: [
|
||||
'Arrow', 'Artemis', 'Ash', 'Aster', 'Avery', 'Basil', 'Ever', 'Fig', 'Finch',
|
||||
'Indigo', 'Jett', 'Juniper', 'Kavi', 'Kaviya', 'Kaviyan', 'Kaviyanan', 'Kay',
|
||||
'Lark', 'Noah', 'Ocean', 'Phoenix', 'Riley', 'River', 'Rory', 'Rowan', 'Sage',
|
||||
'Sawyer', 'Shiloh', 'Sparrow', 'Sutton', 'Tavi', 'Uli', 'Veer', 'Vesper',
|
||||
'Winter', 'Wren', 'Zen', 'Zenith', 'Zephyr', 'Zephyrus'
|
||||
],
|
||||
femaleNames: [
|
||||
'Aarohi', 'Aarushi', 'Abigail', 'Amelia', 'Ananya', 'Anika', 'Anjali',
|
||||
'Anushka', 'Aria', 'Ava', 'Chloe', 'Devi', 'Elina', 'Elizabeth', 'Emily',
|
||||
'Emma', 'Esha', 'Evelyn', 'Grace', 'Harper', 'Isabella', 'Ishani', 'Ishika',
|
||||
'Ishita', 'Layla', 'Lily', 'Madison', 'Margarita', 'Maria', 'Mia', 'Nisha',
|
||||
'Nora', 'Nosheen', 'Olivia', 'Penelope', 'Priya', 'Qadira', 'Riley', 'Scarlett',
|
||||
'Sofia', 'Sophia', 'Tala', 'Ulka', 'Uthra', 'Uthraa', 'Victoria', 'Yasmin',
|
||||
'Zara', 'Zoey', 'Zoya', 'Zulaikha'
|
||||
],
|
||||
maleNames: [
|
||||
'Ahmed', 'Aiden', 'Alexander', 'Benjamin', 'Callum', 'Carter', 'Daniel',
|
||||
'David', 'Dylan', 'Elias', 'Elijah', 'Ethan', 'Ewan', 'Ezra', 'Gavin',
|
||||
'Henry', 'Hudson', 'Jackson', 'Jacob', 'Jaden', 'James', 'Jaxon', 'Jayden',
|
||||
'Jordan', 'Joseph', 'Julian', 'Kian', 'Kianan', 'Kianu', 'Lachlan', 'Leo',
|
||||
'Levi', 'Liam', 'Lincoln', 'Logan', 'Lucas', 'Mason', 'Mateo', 'Matthew',
|
||||
'Michael', 'Mohammed', 'Noah', 'Nolan', 'Oliver', 'Pol', 'Samuel',
|
||||
'Santiago', 'Sebastian', 'Theodore', 'Ulric', 'Wallid', 'William', 'Wyatt'
|
||||
]
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Caractéristiques
|
||||
// ============================================================================
|
||||
|
||||
export const CHARACTERISTIC = {
|
||||
STR: { key: 'STR', label: 'Force', mgt2eKey: 'STR' },
|
||||
DEX: { key: 'DEX', label: 'Dextérité', mgt2eKey: 'DEX' },
|
||||
END: { key: 'END', label: 'Endurance', mgt2eKey: 'END' },
|
||||
INT: { key: 'INT', label: 'Intellect', mgt2eKey: 'INT' },
|
||||
EDU: { key: 'EDU', label: 'Éducation', mgt2eKey: 'EDU' },
|
||||
SOC: { key: 'SOC', label: 'Statut Social', mgt2eKey: 'SOC' }
|
||||
};
|
||||
|
||||
export const CHARACTERISTIC_LIST = [
|
||||
CHARACTERISTIC.STR,
|
||||
CHARACTERISTIC.DEX,
|
||||
CHARACTERISTIC.END,
|
||||
CHARACTERISTIC.INT,
|
||||
CHARACTERISTIC.EDU,
|
||||
CHARACTERISTIC.SOC
|
||||
];
|
||||
|
||||
// Ordre des caractéristiques pour l'UPP
|
||||
export const UPP_ORDER = ['STR', 'DEX', 'END', 'INT', 'EDU', 'SOC'];
|
||||
|
||||
// ============================================================================
|
||||
// Fonctions utilitaires
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Convertit une valeur de caractéristique en code hexadécimal pour UPP
|
||||
* @param {number} value - Valeur de la caractéristique (0-15)
|
||||
* @returns {string} - Code hexadécimal
|
||||
*/
|
||||
export function toHex(value) {
|
||||
return Math.max(0, Math.min(15, Math.floor(value))).toString(16).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcule le DM (Damage Modifier) à partir d'une valeur de caractéristique
|
||||
* @param {number} value - Valeur de la caractéristique
|
||||
* @returns {number} - Modificateur de dégâts
|
||||
*/
|
||||
export function calculateDm(value) {
|
||||
return Math.floor((value - 6) / 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère un nom aléatoire à partir des catalogues
|
||||
* @param {string} genderKey - Clé du genre ('unspecified', 'female', 'male')
|
||||
* @returns {{firstName: string, surname: string, fullName: string}}
|
||||
*/
|
||||
export function generateRandomName(genderKey = 'unspecified') {
|
||||
const genderMap = {
|
||||
unspecified: NAME_CATALOGS.nonGenderedNames,
|
||||
female: NAME_CATALOGS.femaleNames,
|
||||
male: NAME_CATALOGS.maleNames
|
||||
};
|
||||
|
||||
const firstNames = genderMap[genderKey] || NAME_CATALOGS.nonGenderedNames;
|
||||
const surnames = NAME_CATALOGS.surnames;
|
||||
|
||||
const firstName = pickRandomItem(firstNames);
|
||||
const surname = pickRandomItem(surnames);
|
||||
|
||||
return {
|
||||
firstName,
|
||||
surname,
|
||||
fullName: `${firstName} ${surname}`
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sélectionne un élément aléatoire dans un tableau
|
||||
* @template T
|
||||
* @param {T[]} items - Tableau d'éléments
|
||||
* @returns {T} - Élément sélectionné
|
||||
*/
|
||||
export function pickRandomItem(items) {
|
||||
if (!items || items.length === 0) {
|
||||
throw new Error('Cannot pick from empty array');
|
||||
}
|
||||
const index = Math.floor(Math.random() * items.length);
|
||||
return items[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Mélange un tableau (algorithme de Fisher-Yates)
|
||||
* @template T
|
||||
* @param {T[]} array - Tableau à mélanger
|
||||
* @returns {T[]} - Nouveau tableau mélangé
|
||||
*/
|
||||
export function shuffleArray(array) {
|
||||
const newArray = [...array];
|
||||
for (let i = newArray.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[newArray[i], newArray[j]] = [newArray[j], newArray[i]];
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extraire les N premiers éléments d'un tableau et retourner les deux parties
|
||||
* @template T
|
||||
* @param {T[]} array - Tableau source
|
||||
* @param {number} count - Nombre d'éléments à extraire
|
||||
* @returns {[T[], T[]]} - [éléments extraits, éléments restants]
|
||||
*/
|
||||
export function popRandomItems(array, count) {
|
||||
if (!array || array.length === 0 || count <= 0) {
|
||||
return [[], [...array]];
|
||||
}
|
||||
|
||||
const shuffled = shuffleArray(array);
|
||||
const taken = shuffled.slice(0, Math.min(count, shuffled.length));
|
||||
const remaining = shuffled.slice(Math.min(count, shuffled.length));
|
||||
|
||||
return [taken, remaining];
|
||||
}
|
||||
|
||||
/**
|
||||
* Trouve un rôle par sa clé
|
||||
* @param {string} key - Clé du rôle
|
||||
* @returns {Object|null} - Objet rôle ou null
|
||||
*/
|
||||
export function getRoleByKey(key) {
|
||||
const found = ROLE_LIST.find(r => r.key === key);
|
||||
return found || ROLE.PILOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trouve une catégorie de citoyen par sa clé
|
||||
* @param {string} key - Clé de la catégorie
|
||||
* @returns {Object} - Objet catégorie
|
||||
*/
|
||||
export function getCitizenCategoryByKey(key) {
|
||||
const found = CITIZEN_CATEGORY_LIST.find(c => c.key === key);
|
||||
return found || CITIZEN_CATEGORY.AVERAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trouve un niveau d'expérience par sa clé
|
||||
* @param {string} key - Clé du niveau
|
||||
* @returns {Object} - Objet niveau d'expérience
|
||||
*/
|
||||
export function getExperienceLevelByKey(key) {
|
||||
const found = EXPERIENCE_LEVEL_LIST.find(e => e.key === key);
|
||||
return found || EXPERIENCE_LEVEL.REGULAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trouve un genre par sa clé
|
||||
* @param {string} key - Clé du genre
|
||||
* @returns {Object} - Objet genre
|
||||
*/
|
||||
export function getGenderByKey(key) {
|
||||
const found = GENDER_LIST.find(g => g.key === key);
|
||||
return found || GENDER.UNSPECIFIED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtient les compétences pour un rôle
|
||||
* @param {string} roleKey - Clé du rôle
|
||||
* @returns {string[]} - Tableau de compétences
|
||||
*/
|
||||
export function getSkillsForRole(roleKey) {
|
||||
return ROLE_SKILLS[roleKey] || ROLE_SKILLS.pilot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtient les priorités de caractéristiques pour un rôle
|
||||
* @param {string} roleKey - Clé du rôle
|
||||
* @returns {Object} - Priorités de caractéristiques
|
||||
*/
|
||||
export function getCharacteristicPrioritiesForRole(roleKey) {
|
||||
return CHARACTERISTIC_PRIORITIES[roleKey] || CHARACTERISTIC_PRIORITIES.pilot;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Données par défaut
|
||||
// ============================================================================
|
||||
|
||||
export const DEFAULT_OPTIONS = {
|
||||
citizenCategory: CITIZEN_CATEGORY.AVERAGE.key,
|
||||
experience: EXPERIENCE_LEVEL.REGULAR.key,
|
||||
role: ROLE.PILOT.key,
|
||||
gender: GENDER.UNSPECIFIED.key,
|
||||
createActor: false,
|
||||
actorName: '',
|
||||
openCreatedActor: true
|
||||
};
|
||||
Reference in New Issue
Block a user