Génération aléatoire d'archétype

This commit is contained in:
2026-06-19 23:50:58 +02:00
parent 749eb5ee13
commit f8a20b90ff
5 changed files with 95 additions and 27 deletions

View File

@@ -1,5 +1,14 @@
# 13.0
## 13.0.46 - L'archétype d'Illisys
- ajout d'une génération d'archétype aléatoire
- respecte les niveaux d'archétype déjà alloués
- l'archétype alloué est supérieur au niveau actuel (si c'est possible)
- les compétences supérieures à 0 ont plus de chances d'avoir les niveaux d'archétype élevés
- si tous les niveaux d'archétype supérieurs à une compétences sont déjà alloué,
l'archétype est au niveau actuel de la compétence
## 13.0.45 - L'endépôté d'Illisys
- nouvelle correction du manifest

View File

@@ -275,6 +275,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
await this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value));
});
this.html.find('.nouvelle-incarnation').click(async event => await this.actor.nouvelleIncarnation())
this.html.find('.repartition-archetype-aleatoire').click(async event => await this.actor.repartitionArchetypeAleatoire())
}
// On pts de reve change

View File

@@ -2975,19 +2975,19 @@ export class RdDActor extends RdDBaseActorSang {
}
async nouvelleIncarnation() {
let incarnation = this.toObject();
let incarnation = this.toObject()
incarnation.items = Array.from(this.items.filter(it => it.type == ITEM_TYPES.competence),
incarnation.items = Array.from(this.itemTypes[ITEM_TYPES.competence],
it => {
it = it.toObject();
it.id = undefined;
it.system.niveau = it.system.base;
it.system.niveau_archetype = Math.max(it.system.niveau + (it.system.xp > 0 ? 1 : 0), it.system.niveau_archetype);
it.system.xp = 0;
it.system.xp_sort = 0;
it.system.default_diffLibre = 0;
return it;
});
it = it.toObject()
it.id = undefined
it.system.niveau = it.system.base
it.system.niveau_archetype = Math.max(it.system.niveau + (it.system.xp > 0 ? 1 : 0), it.system.niveau_archetype)
it.system.xp = 0
it.system.xp_sort = 0
it.system.default_diffLibre = 0
return it
})
incarnation.name = 'Réincarnation de ' + incarnation.name
incarnation.system = {
@@ -3002,12 +3002,57 @@ export class RdDActor extends RdDBaseActorSang {
'reve.reve.value': this.system.carac.reve.value,
subacteurs: { suivants: [], montures: [], vehicules: [] },
}
incarnation = await RdDBaseActor.create(incarnation);
await incarnation.deleteEmbeddedDocuments('ActiveEffect', incarnation.getEmbeddedCollection("ActiveEffect").map(it => it.id));
await incarnation.remiseANeuf();
incarnation.sheet.render(true);
incarnation = await RdDBaseActor.create(incarnation)
await incarnation.deleteEmbeddedDocuments('ActiveEffect', incarnation.getEmbeddedCollection("ActiveEffect").map(it => it.id))
await incarnation.remiseANeuf()
incarnation.sheet.render(true)
}
async repartitionArchetypeAleatoire() {
const nivArchetypeDisponibles = RdDItemCompetence.computeResumeArchetype(this.itemTypes[ITEM_TYPES.competence])
.filter(it => it.reste > 0)
function proba(nivDispo, niveauActuel) {
return niveauActuel > 0 ? (nivDispo.reste + 3) : nivDispo.reste
}
async function takeNiveauArchetypeRandom(niveauMin) {
const potential = nivArchetypeDisponibles.filter(it => it.niveau >= niveauMin)
const totalChances = potential.map(it => proba(it, niveauMin)).reduce(Misc.sum(), 0)
if (totalChances > 0) {
let random = await Misc.random(totalChances)
for (const selected of potential) {
if (selected.reste > 0) {
const chances = proba(selected, niveauMin)
if (random <= chances) {
selected.nombre++
selected.reste--
return selected.niveau
}
random -= chances
}
}
}
return Math.max(0, niveauMin)
}
const compsByNiveau = Misc.classify(
this.itemTypes[ITEM_TYPES.competence].filter(it => it.system.niveau_archetype <= 0),
it => Math.max(0, it.system.niveau))
const niveaux = Object.keys(compsByNiveau).sort(Misc.descending())
const updates = []
for (let i = 0; i < niveaux.length; i++) {
const competencesDuNiveau = Misc.shuffled(compsByNiveau[niveaux[i]])
for (let j = 0; j < competencesDuNiveau.length; j++) {
const competence = competencesDuNiveau[j]
const nivArchetype = await takeNiveauArchetypeRandom(competence.system.niveau)
updates.push({ _id: competence.id, 'system.niveau_archetype': nivArchetype })
}
}
await this.updateEmbeddedDocuments('Item', updates)
}
/* -------------------------------------------- */
async _rollArtV2(oeuvreId) {

View File

@@ -24,8 +24,7 @@ export class Misc {
return text.charAt(0).toLowerCase() + text.slice(1);
}
static stripHtml(html)
{
static stripHtml(html) {
const tmp = document.createElement("DIV")
tmp.innerHTML = html
return tmp.textContent || tmp.innerText || ""
@@ -329,4 +328,19 @@ export class Misc {
'-o-transform': rotation
};
}
static async random(count) {
const roll = new Roll(`1d${count}`)
await roll.evaluate()
return roll.total
}
static shuffled(source) {
const result = source.slice(0)
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result
}
}

View File

@@ -1,21 +1,20 @@
<div>
<ul class="item-list">
<li><a class="repartition-archetype-aleatoire chat-card-button flexrow" data-tooltip="Répartition aléatoire des niveaux d'archétype restants">
<i class="fa-solid fa-circle-user-clock"></i><i class="fa-solid fa-shuffle"></i></a>
{{#if @root.options.isGM}}
<li>
<a class="nouvelle-incarnation chat-card-button" data-tooltip="Création d'une nouvelle incarnation de l'archétype">
<i class="fa-solid fa-person-circle-plus"></i> Nouvelle incarnation</a>
<a class="nouvelle-incarnation chat-card-button flexrow" data-tooltip="Création d'une nouvelle incarnation de l'archétype">
<i class="fa-regular fa-skull"></i><i class="fa-solid fa-person-circle-plus"></i></a>
</li>
{{/if}}
<li><hr></li>
<li>Niveaux d'archétype</li>
{{#if calc.comptageArchetype}}
{{#each calc.comptageArchetype as |archetype|}}
<li class="item flexrow">
<label class="generic-label">
Niveaux {{plusMoins archetype.niveau}} : {{archetype.nombre}} / {{archetype.nombreMax}}
</label>
</li>
<li class="item flexrow">
<label class="generic-label">
Niveaux {{plusMoins archetype.niveau}} : {{archetype.nombre}} / {{archetype.nombreMax}}
</label>
</li>
{{/each}}
{{/if}}
</ul>