319 lines
26 KiB
TypeScript
319 lines
26 KiB
TypeScript
import type { Ability, CharacterConfig, Feature, FeatureEffect, FeatureItem, MainStat, TrainingOption } from "~/types/character";
|
|
import { div, dom, icon, text, type NodeChildren } from "./dom.util";
|
|
import { MarkdownEditor } from "./editor.util";
|
|
import { button, combobox, fakeA, input, numberpicker, select } from "./proses";
|
|
import { popper, tooltip } from "./floating.util";
|
|
import { mainStatShortTexts, mainStatTexts } from "./character.util";
|
|
import config from "#shared/character-config.json";
|
|
import { getID, ID_SIZE } from "./general.util";
|
|
import renderMarkdown from "./markdown.util";
|
|
|
|
export class FeatureEditor
|
|
{
|
|
private _container: HTMLDivElement;
|
|
|
|
private _success?: Function;
|
|
private _failure?: Function;
|
|
private _feature?: Feature;
|
|
|
|
private _idInput: HTMLInputElement;
|
|
private _table: HTMLDivElement;
|
|
|
|
constructor()
|
|
{
|
|
this._idInput = dom("input", { attributes: { 'disabled': true }, class: `mx-4 text-light-70 dark:text-dark-70 appearance-none outline-none px-3 py-1 focus:shadow-raw transition-[box-shadow] border bg-light-25 dark:bg-dark-25 border-light-30 dark:border-dark-30` });
|
|
this._table = div('grid grid-cols-2 gap-4 px-2');
|
|
this._container = dom('div', { attributes: { 'data-state': 'inactive' }, class: 'border-light-35 dark:border-dark-35 bg-light-10 dark:bg-dark-10 border-l absolute top-0 bottom-0 right-0 w-[10%] data-[state=active]:w-1/2 flex flex-col gap-2 text-light-100 dark:text-dark-100 p-8 transition-[width] transition-delay-[150ms]' }, [
|
|
div('flex flex-row justify-between items-center', [
|
|
tooltip(button(icon('radix-icons:check', { width: 20, height: 20 }), () => {
|
|
this._success!(this._feature);
|
|
MarkdownEditor.singleton.onChange = undefined;
|
|
}, 'p-1'), 'Valider', 'left'),
|
|
dom('label', { class: 'flex justify-center items-center my-2' }, [
|
|
dom('span', { class: 'pb-1 md:p-0', text: "ID" }),
|
|
this._idInput
|
|
]),
|
|
tooltip(button(icon('radix-icons:cross-1', { width: 20, height: 20 }), () => {
|
|
this._failure!(this._feature);
|
|
MarkdownEditor.singleton.onChange = undefined;
|
|
}, 'p-1'), 'Annuler', 'left'),
|
|
]),
|
|
dom('span', { class: 'flex flex-col justify-start items-start my-2 gap-4' }, [
|
|
div('flex w-full items-center justify-between', [
|
|
dom('span', { class: 'pb-1 md:p-0', text: "Description" }),
|
|
tooltip(button(icon('radix-icons:clipboard', { width: 20, height: 20 }), () => {
|
|
MarkdownEditor.singleton.content = this._feature?.effect.map(e => textFromEffect(e)).join('\n') ?? this._feature?.description ?? MarkdownEditor.singleton.content;
|
|
}, 'p-1'), 'Description automatique', 'left'),
|
|
]),
|
|
div('p-1 border border-light-40 dark:border-dark-40 w-full bg-light-25 dark:bg-dark-25 min-h-48 max-h-[32rem]', [ MarkdownEditor.singleton.dom ]),
|
|
]),
|
|
div('flex flex-col gap-2 w-full', [
|
|
div('flex flex-row justify-between', [
|
|
dom('h3', { class: 'text-lg font-bold', text: 'Effets' }),
|
|
tooltip(button(icon('radix-icons:plus', { width: 20, height: 20 }), () => {
|
|
this._table.appendChild(this._edit({ id: getID(ID_SIZE) }));
|
|
}, 'p-1'), 'Ajouter', 'left'),
|
|
]),
|
|
this._table,
|
|
])
|
|
]);
|
|
}
|
|
edit(feature: Feature): Promise<Feature>
|
|
{
|
|
return new Promise((success, failure) => {
|
|
this._success = success;
|
|
this._failure = failure;
|
|
|
|
this._feature = JSON.parse(JSON.stringify(feature)) as Feature;
|
|
|
|
this._table.replaceChildren(...this._feature.effect.map(this._renderEffect.bind(this)));
|
|
this._idInput.value = this._feature.id;
|
|
MarkdownEditor.singleton.onChange = (e) => this._feature!.description = e;
|
|
MarkdownEditor.singleton.content = this._feature.description;
|
|
});
|
|
}
|
|
private _renderEffect(effect: FeatureItem): HTMLDivElement
|
|
{
|
|
const content = div('border border-light-30 dark:border-dark-30 col-span-1', [ div('flex justify-between items-stretch', [
|
|
div('px-4 flex items-center h-full', [ renderMarkdown(textFromEffect(effect), undefined, { tags: { a: fakeA } }) ]),
|
|
div('flex', [ tooltip(button(icon('radix-icons:pencil-1'), () => {
|
|
this._table.replaceChild(this._edit(effect), content);
|
|
}, 'p-2 -m-px border border-light-35 dark:border-dark-35 hover:border-light-50 dark:hover:border-dark-50'), "Modifier", "bottom"), tooltip(button(icon('radix-icons:trash'), () => {
|
|
this._feature!.effect = this._feature!.effect.filter(e => e.id !== effect.id);
|
|
content.remove();
|
|
}, 'p-2 -m-px border border-light-35 dark:border-dark-35 hover:border-light-50 dark:hover:border-dark-50'), "Supprimer", "bottom") ])
|
|
]) ]);
|
|
return content;
|
|
}
|
|
private _edit(effect: FeatureItem): HTMLDivElement
|
|
{
|
|
const match = (effect: FeatureItem): Partial<FeatureItem> | undefined => {
|
|
switch(effect.category)
|
|
{
|
|
case 'value':
|
|
return choices.find(e => e.value.category === 'value' && e.value.property === effect.property)?.value;
|
|
/* case 'choice':
|
|
return choices.find(e => e.value.category === 'choice' && e.value. === effect.property); */
|
|
case 'list':
|
|
return choices.find(e => e.value.category === 'list' && e.value.list === effect.list)?.value;
|
|
}
|
|
};
|
|
const approve = () => {
|
|
const idx = this._feature!.effect.findIndex(e => e.id === buffer.id);
|
|
|
|
if(idx === -1)
|
|
this._feature!.effect.push(buffer);
|
|
else
|
|
this._feature!.effect[idx] = buffer;
|
|
|
|
this._table.replaceChild(this._renderEffect(buffer), content);
|
|
}, reject = () => {
|
|
const idx = this._feature!.effect.findIndex(e => e.id === buffer.id);
|
|
|
|
if(idx === -1)
|
|
content.remove();
|
|
else
|
|
this._table.replaceChild(this._renderEffect(effect), content);
|
|
}
|
|
let buffer = JSON.parse(JSON.stringify(effect)) as FeatureItem;
|
|
|
|
const redraw = () => {
|
|
let top: NodeChildren = [], bottom: NodeChildren = [];
|
|
switch(buffer.category)
|
|
{
|
|
case 'value':
|
|
const summaryText = text(textFromEffect(buffer));
|
|
top = [
|
|
select([ { text: '+', value: 'add' }, ['speed', 'capacity'].includes(buffer.property) ? { text: '=', value: 'set' } : undefined ], { defaultValue: buffer.operation, change: (value) => { (buffer as Extract<FeatureEffect, { category: "value" }>).operation = value as 'add' | 'set'; summaryText.textContent = textFromEffect(buffer); }, class: { container: 'bg-light-25 dark:bg-dark-25 !-m-px h-[36px]' } }),
|
|
typeof buffer.value === 'number' ? numberpicker({ defaultValue: buffer.value, input: (value) => { (buffer as Extract<FeatureEffect, { category: "value" }>).value = value; summaryText.textContent = textFromEffect(buffer); }, class: 'bg-light-25 dark:bg-dark-25 !-m-px h-[36px]' }) : select<`modifier/${MainStat}` | false>([...Object.entries(mainStatShortTexts).map(e => ({ text: 'Mod. de ' + e[1], value: `modifier/${e[0]}` as `modifier/${MainStat}` })), buffer.operation === 'add' ? undefined : { text: 'Interdit', value: false }], { class: { container: 'w-[160px] bg-light-25 dark:bg-dark-25 !-m-px h-[36px]' }, defaultValue: buffer.value, change: (value) => { (buffer as Extract<FeatureEffect, { category: "value" }>).value = value; summaryText.textContent = textFromEffect(buffer); } }),
|
|
button(icon('radix-icons:update'), () => {
|
|
(buffer as Extract<FeatureEffect, { category: "value" }>).value = (typeof (buffer as Extract<FeatureEffect, { category: "value" }>).value === 'number' ? '' as any as false : 0);
|
|
const element = redraw();
|
|
this._table.replaceChild(element, content);
|
|
content = element;
|
|
summaryText.textContent = textFromEffect(buffer);
|
|
}, 'px-2 -m-px border border-light-35 dark:border-dark-35 hover:border-light-50 dark:hover:border-dark-50'),
|
|
];
|
|
bottom = [summaryText];
|
|
break;
|
|
case 'list':
|
|
if(buffer.action === 'add')
|
|
{
|
|
if(buffer.list === 'spells')
|
|
{
|
|
bottom = [ combobox(config.spells.map(e => ({ text: e.name, value: e.id })), { defaultValue: buffer.item, change: (value) => (buffer as Extract<FeatureEffect, { category: "list" }>).item = value, class: { container: 'bg-light-25 dark:bg-dark-25 !-m-px h-[36px]' } }) ];
|
|
}
|
|
else
|
|
{
|
|
const editor = new MarkdownEditor();
|
|
editor.content = buffer.item;
|
|
editor.onChange = (item) => (buffer as Extract<FeatureEffect, { category: "list" }>).item = item;
|
|
|
|
bottom = [ div('px-4 py-1', [ editor.dom ]) ];
|
|
}
|
|
}
|
|
top = [ select([ { text: 'Ajouter', value: 'add' }, { text: 'Supprimer', value: 'remove' } ], { defaultValue: buffer.action, change: (value) => (buffer as Extract<FeatureEffect, { category: "list" }>).action = value as 'add' | 'remove', class: { container: 'bg-light-25 dark:bg-dark-25 !-m-px h-[36px] w-32' } }) ];
|
|
break;
|
|
default: break;
|
|
}
|
|
return div('border border-light-30 dark:border-dark-30 col-span-1 row-span-2', [ div('flex justify-between items-stretch', [
|
|
div('flex flex-row', [
|
|
combobox(choices, { defaultValue: match(buffer), class: { container: 'bg-light-25 dark:bg-dark-25 w-[250px] -m-px h-[36px]' }, change: (e) => {
|
|
buffer = { id: buffer.id, ...e } as FeatureItem;
|
|
const element = redraw();
|
|
this._table.replaceChild(element, content);
|
|
content = element;
|
|
} }),
|
|
...top,
|
|
]),
|
|
div('flex', [ tooltip(button(icon('radix-icons:check'), approve, 'p-2 -m-px border border-light-35 dark:border-dark-35 hover:border-light-50 dark:hover:border-dark-50'), "Valider", "bottom"), tooltip(button(icon('radix-icons:cross-1'), reject, 'p-2 -m-px border border-light-35 dark:border-dark-35 hover:border-light-50 dark:hover:border-dark-50'), "Annuler", "bottom") ])
|
|
]), div('flex border-t border-light-35 dark:border-dark-35 max-h-[300px] min-h-[36px] overflow-auto', bottom) ]);
|
|
}
|
|
|
|
let content = redraw();
|
|
return content;
|
|
}
|
|
get container()
|
|
{
|
|
return this._container;
|
|
}
|
|
}
|
|
|
|
const choices: Array<{ text: string, value: Partial<FeatureItem> }> = [
|
|
{ text: 'PV max', value: { category: 'value', property: 'health', operation: 'add', value: 0 }, },
|
|
{ text: 'Mana max', value: { category: 'value', property: 'mana', operation: 'add', value: 0 }, },
|
|
{ text: 'Nombre de sorts maitrisés', value: { category: 'value', property: 'spellslots', operation: 'add', value: 0 }, },
|
|
{ text: 'Nombre d\'œuvres maitrisés', value: { category: 'value', property: 'artslots', operation: 'add', value: 0 }, },
|
|
{ text: 'Vitesse de course', value: { category: 'value', property: 'speed', operation: 'add', value: 0 }, },
|
|
{ text: 'Poids max', value: { category: 'value', property: 'capacity', operation: 'add', value: 0 }, },
|
|
{ text: 'Initiative', value: { category: 'value', property: 'initiative', operation: 'add', value: 0 }, },
|
|
{ text: 'Points d\'entrainement', value: { category: 'value', property: 'training', operation: 'add', value: 0 }, },
|
|
{ text: 'Points de compétence', value: { category: 'value', property: 'ability', operation: 'add', value: 0 }, },
|
|
{ text: 'Sort bonus', value: { category: 'list', list: 'spells', action: 'add' }, },
|
|
{ text: 'Action', value: { category: 'list', list: 'action', action: 'add' }, },
|
|
{ text: 'Réaction', value: { category: 'list', list: 'reaction', action: 'add' }, },
|
|
{ text: 'Action libre', value: { category: 'list', list: 'freeaction', action: 'add' }, },
|
|
{ text: 'Passif', value: { category: 'list', list: 'passive', action: 'add' }, },
|
|
{ text: 'Choix', value: { category: 'choice', options: [] }, },
|
|
];
|
|
function textFromEffect(effect: FeatureItem)
|
|
{
|
|
if(effect.category === 'value')
|
|
{
|
|
switch(effect.property)
|
|
{
|
|
case 'health':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+', text: '+Mod. de ' }, suffix: { truely: ' PV max.' } }) : textFromValue(effect.value, { prefix: { truely: 'PV max égal à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (PV = interdit).' });
|
|
case 'mana':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+', text: '+Mod. de ' }, suffix: { truely: ' mana max.' } }) : textFromValue(effect.value, { prefix: { truely: 'Mana max égal à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Mana = interdit).' });
|
|
case 'spellslots':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+', text: '+Mod. de ' }, suffix: { truely: ' sort(s) maitrisé(s).' } }) : textFromValue(effect.value, { prefix: { truely: 'Sorts maitrisés fixé à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Sorts = interdit).' });
|
|
case 'artslots':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+', text: '+Mod. de ' }, suffix: { truely: ' œuvre(s) maitrisé(s).' } }) : textFromValue(effect.value, { prefix: { truely: 'Œuvres maitrisés fixé à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Œuvres = interdit).' });
|
|
case 'speed':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+', text: '+Mod. de ' }, suffix: { truely: ' case(s) de course.' }, falsely: '+0 cases de course' }) : textFromValue(effect.value, { prefix: { truely: 'Vitesse de course de ' }, suffix: { truely: ' case(s).' }, falsely: 'Déplacement impossible.' });
|
|
case 'capacity':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+', text: '+Mod. de ' }, suffix: { truely: ' unité(s) d\'quipement.' } }) : textFromValue(effect.value, { prefix: { truely: 'Capacité d\'equipement fixé à ' }, suffix: { truely: ' unité(s).' }, falsely: 'Impossible de posséder du materiel.' });
|
|
case 'initiative':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+', text: '+Mod. de ' }, suffix: { truely: ' à l\'itiniative.' } }) : textFromValue(effect.value, { prefix: { truely: 'Initiative fixé à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Initiative = interdit).' });
|
|
case 'training':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+', text: '+Mod. de ' }, suffix: { truely: ' point(s) d\'entrainement.' } }) : `Opération interdite (Entrainement fixe).`;
|
|
case 'ability':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+', text: '+Mod. de ' }, suffix: { truely: ' point(s) de compétence.' } }) : `Opération interdite (Compétences fixe).`;
|
|
default: break;
|
|
}
|
|
|
|
const splited = effect.property.split('/');
|
|
switch(splited[0])
|
|
{
|
|
case 'spellranks':
|
|
return '';
|
|
case 'defense':
|
|
switch(splited[1])
|
|
{
|
|
case 'hardcap':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Défense max ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Défense max fixé à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Hardcap = interdit).' });
|
|
case 'static':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Base de défense ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Base de défense fixé à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Static = interdit).' });
|
|
case 'activeparry':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Parade active ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Parade active fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Active parry = interdit).' });
|
|
case 'activedodge':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Esquive active ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Esquive active fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Active dodge = interdit).' });
|
|
case 'passiveparry':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Parade passive ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Parade passive fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Passive parry = interdit).' });
|
|
case 'passivedodge':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Esquive passive ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Esquive passive fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Passive dodge = interdit).' });
|
|
default: return 'Défense inconnue.';
|
|
}
|
|
case 'mastery':
|
|
switch(splited[1])
|
|
{
|
|
case 'strength':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Maitrise des armes (for.) ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Maitrise des armes (for.) fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Maitrise for = interdit).' });
|
|
case 'dexterity':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Maitrise des armes (dex.) ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Maitrise des armes (dex.) fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Maitrise dex = interdit).' });
|
|
case 'shield':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Maitrise des boucliers ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Maitrise des boucliers fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Maitrise boucliers = interdit).' });
|
|
case 'armor':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Maitrise des armure ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Maitrise des armure fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Maitrise armure = interdit).' });
|
|
case 'multiattack':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Attaque multiple ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Attaque multiple fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Attaque multiple = interdit).' });
|
|
case 'magicpower':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Arbre de magie (Puissance) ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Arbre de magie (Puissance) fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Maitrise puissance = interdit).' });
|
|
case 'magicspeed':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Arbre de magie (Rapidité) ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Arbre de magie (Rapidité) fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Maitrise rapidité = interdit).' });
|
|
case 'magicelement':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Arbre de magie (Elements) ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Arbre de magie (Elements) fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Maitrise elements = interdit).' });
|
|
case 'magicinstinct':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: 'Arbre de magie (Instinct) ', positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: 'Arbre de magie (Instinct) fixée à ' }, suffix: { truely: '.' }, falsely: 'Opération interdite (Maitrise instinct = interdit).' });
|
|
default: return 'Maitrise inconnue.';
|
|
}
|
|
/* case 'resistance':
|
|
return splited[1] ? config.resistances[splited[1] as string].name : 'résistance inconnue'; */
|
|
case 'abilities':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { truely: `${config.abilities[splited[1] as Ability].name} `, positive: '+', text: '+Mod. de ' }, suffix: { truely: '.' } }) : textFromValue(effect.value, { prefix: { truely: `${config.abilities[splited[1] as Ability].name} fixé à ` }, suffix: { truely: '.' }, falsely: `Echec automatique de ${`${config.abilities[splited[1] as Ability].name}.`}` });
|
|
case 'modifier':
|
|
return effect.operation === 'add' ? textFromValue(effect.value, { prefix: { positive: '+' }, suffix: { truely: ` au mod. de ${mainStatTexts[splited[1] as MainStat]}.` } }) : textFromValue(effect.value, { prefix: { truely: `Mod. de ${mainStatTexts[splited[1] as MainStat]} fixé à ` }, suffix: { truely: '.' }, falsely: `Opération interdite (Mod. de ${mainStatShortTexts[splited[1] as MainStat]} = interdit).` });
|
|
default: break;
|
|
}
|
|
|
|
return `Inconnu ("${effect.property}")`;
|
|
}
|
|
else if(effect.category === 'list')
|
|
{
|
|
switch(effect.list)
|
|
{
|
|
case 'action':
|
|
case 'reaction':
|
|
case 'freeaction':
|
|
case 'passive':
|
|
return effect.action === 'add' ? effect.item : 'Suppression d\'effet.';
|
|
case 'spells':
|
|
return effect.action === 'add' ? `Maitrise du sort "${config.spells.find(e => e.id === effect.item) ?? 'Sort inconnu'}".` : `Perte de maitrise du sort "${config.spells.find(e => e.id === effect.item) ?? 'Sort inconnu'}".`;
|
|
}
|
|
}
|
|
else if(effect.category === 'choice')
|
|
{
|
|
return `Choix (WIP)`;
|
|
}
|
|
else
|
|
{
|
|
return `Inconnu`;
|
|
}
|
|
}
|
|
function textFromValue(value: `modifier/${MainStat}` | number | false, settings?: {
|
|
prefix?: { text?: string, positive?: string, negative?: string, truely?: string },
|
|
suffix?: { text?: string, positive?: string, negative?: string, truely?: string },
|
|
falsely?: string
|
|
})
|
|
{
|
|
if(typeof value === 'string')
|
|
return `${settings?.prefix?.truely?.replaceAll('(s)', 's') ?? ''}${settings?.prefix?.text?.replaceAll('(s)', 's') ?? ''}${mainStatShortTexts[value.split('/')[1] as MainStat] ?? 'inconnu'}${settings?.suffix?.text?.replaceAll('(s)', 's') ?? ''}${settings?.suffix?.truely?.replaceAll('(s)', 's') ?? ''}`;
|
|
else if(value === false)
|
|
return settings?.falsely ?? '0';
|
|
else if(value >= 0)
|
|
return `${settings?.prefix?.truely?.replaceAll('(s)', value > 1 ? 's' : '') ?? ''}${settings?.prefix?.positive?.replaceAll('(s)', value > 1 ? 's' : '') ?? ''}${value.toString(10)}${settings?.suffix?.positive?.replaceAll('(s)', value > 1 ? 's' : '') ?? ''}${settings?.suffix?.truely?.replaceAll('(s)', value > 1 ? 's' : '') ?? ''}`;
|
|
else
|
|
return `${settings?.prefix?.truely?.replaceAll('(s)', value < -1 ? 's' : '') ?? ''}${settings?.prefix?.negative?.replaceAll('(s)', value < -1 ? 's' : '') ?? ''}${value.toString(10)}${settings?.suffix?.negative?.replaceAll('(s)', value < -1 ? 's' : '') ?? ''}${settings?.suffix?.truely?.replaceAll('(s)', value < -1 ? 's' : '') ?? ''}`;
|
|
}
|