Compare commits

..

4 Commits

Author SHA1 Message Date
a72108db5b Rework combat 2023-04-08 18:50:30 +02:00
6a46faadc2 Rework combat 2023-04-08 18:49:54 +02:00
e95f7de0c5 Fix divers 2023-04-08 09:55:08 +02:00
9d3ef8cbeb CSS journal fix 2023-04-07 16:56:37 +02:00
14 changed files with 262 additions and 144 deletions

View File

@@ -61,6 +61,7 @@ export class HeritiersActorSheet extends ActorSheet {
secretsdecouverts: await TextEditor.enrichHTML(this.object.system.biodata.secretsdecouverts, {async: true}),
questions: await TextEditor.enrichHTML(this.object.system.biodata.questions, {async: true}),
habitat: await TextEditor.enrichHTML(this.object.system.biodata.habitat, {async: true}),
playernotes: await TextEditor.enrichHTML(this.object.system.biodata.playernotes, {async: true}),
options: this.options,
owner: this.document.isOwner,
editScore: this.options.editScore,

View File

@@ -160,7 +160,7 @@ export class HeritiersActor extends Actor {
/* -------------------------------------------- */
prepareUtileSkill(item) {
let specList = []
if (item.system.categorie == "utile") {
if (item && item.system.categorie && item.system.categorie == "utile") {
for (let spec of item.system.specialites) {
specList.push(spec.name)
}
@@ -480,6 +480,20 @@ export class HeritiersActor extends Actor {
}
return talents
}
/* -------------------------------------------- */
getCurrentParade() {
if ( this.system.statutmasque == "masque") {
return this.system.combat.parade.masquee
}
return this.system.combat.parade.demasquee
}
/* -------------------------------------------- */
getCurrentEsquive() {
if ( this.system.statutmasque == "masque") {
return this.system.combat.esquive.masquee
}
return this.system.combat.esquive.demasquee
}
/* -------------------------------------------- */
getTricherie() {
@@ -522,9 +536,15 @@ export class HeritiersActor extends Actor {
}
if (compName) {
rollData.competence = duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
this.prepareUtileSkill(rollData.competence)
rollData.actionImg = rollData.competence?.img
if (rollData.competence && rollData.competence.name) {
this.prepareUtileSkill(rollData.competence)
rollData.actionImg = rollData.competence?.img
} else {
rollData.competence = undefined
}
}
HeritiersUtility.updateWithTarget(rollData)
return rollData
}
/* -------------------------------------------- */

View File

@@ -64,20 +64,32 @@ export const HERITIERS_CONFIG = {
"demasque": "Démasqué"
},
seuilsDifficulte: {
"0": "Aucun/Non applicable",
"-1": "Aucun/Non applicable",
"5": "Enfantine",
"6": "Triviale",
"7": "Moins Triviale",
"8": "Aisée",
"7": "Moins Aisée",
"10": "Normale",
"11": "Moins Normale",
"12": "Compliquée",
"13": "Plus Compliquée",
"14": "Difficile",
"15": "Plus Difficile",
"16": "Très Difficile",
"17": "Très Très Difficile",
"18": "Critique",
"19": "Plus Critique",
"20": "Insurmontable",
"20": "Très Insurmontable",
"22": "Surhumaine",
"23": "Très Surhumaine",
"24": "Epique",
"25": "Plus Epique",
"26": "Légendaire",
"26": "Très Légendaire",
"28": "Mythique",
"29": "Plus Mythique",
"30": "Divine"
},

View File

@@ -13,32 +13,46 @@ export class HeritiersRollDialog extends Dialog {
/* -------------------------------------------- */
constructor(actor, rollData, html, options, close = undefined) {
let buttons = {
rolld8: {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d8",
callback: () => { this.roll("d8") }
},
rolld10: {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d10",
callback: () => { this.roll("d10") }
},
rolld12: {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d12",
callback: () => { this.roll("d12") }
}
}
if (rollData.tricherie) {
buttons["rollTricherie"] = {
icon: '<i class="fas fa-check"></i>',
label: "Lancer avec 1 Point de Tricherie",
callback: () => { this.roll("tricherie") }
}
}
if (rollData.heritage) {
buttons["rollHeritage"] = {
icon: '<i class="fas fa-check"></i>',
label: "Lancer avec 1 Point d'Héritage",
callback: () => { this.roll("heritage") }
}
}
buttons["Cancel"] = {
icon: '<i class="fas fa-times"></i>',
label: "Annuler",
callback: () => { this.close() }
}
let conf = {
title: "Test de Capacité",
content: html,
buttons:
{
rolld8: {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d8",
callback: () => { this.roll("d8") }
},
rolld10: {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d10",
callback: () => { this.roll("d10") }
},
rolld12: {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d12",
callback: () => { this.roll("d12") }
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: "Annuler",
callback: () => { this.close() }
}
},
buttons: buttons,
close: close
}
// Overwrite in case of carac only -> 1d10
@@ -64,7 +78,16 @@ export class HeritiersRollDialog extends Dialog {
/* -------------------------------------------- */
roll(dice) {
this.rollData.mainDice = dice
if (dice == "heritage") {
this.rollData.useHeritage = true
}
else {
if (dice == "tricherie") {
this.rollData.useTricherie = true
} else {
this.rollData.mainDice = dice
}
}
HeritiersUtility.rollHeritiers(this.rollData)
}

View File

@@ -42,12 +42,12 @@ export class HeritiersUtility {
/* -------------------------------------------- */
static sortByName(table) {
static sortByName(table) {
return table.sort(function (a, b) {
return a.name.localeCompare(b.name);
})
}
/* -------------------------------------------- */
static sortArrayObjectsByName(myArray) {
myArray.sort((a, b) => {
@@ -269,68 +269,106 @@ export class HeritiersUtility {
/* -------------------------------------------- */
static computeMonnaieDetails(valueSC) {
let po = Math.floor(valueSC / 400)
let pa = Math.floor((valueSC - (po*400)) / 20)
let sc = valueSC - (po*400) - (pa*20)
let pa = Math.floor((valueSC - (po * 400)) / 20)
let sc = valueSC - (po * 400) - (pa * 20)
return {
po: po, pa: pa, sc: sc, valueSC: valueSC
po: po, pa: pa, sc: sc, valueSC: valueSC
}
}
/* -------------------------------------------- */
static incDecHeritage() {
}
/* -------------------------------------------- */
static computeResult(actor, rollData) {
rollData.diceResult = -1
let resTab = []
for ( let res of rollData.roll.terms[0].results) {
rollData.diceResult = Math.max(res.result, rollData.diceResult)
resTab.push(res.result)
}
let isFailure = false
if (rollData.mainDice.includes("d10")) {
if ( rollData.diceResult == 1) {
rollData.finalResult -= 3
isFailure = true
}
}
if (rollData.mainDice.includes("d12")) {
if ( rollData.diceResult == 1 || rollData.diceResult == 2) {
rollData.finalResult -= 5
isFailure = true
}
}
// Heritage/Tricherie management
let isTricherieHeritage = rollData.useHeritage || rollData.useTricherie
rollData.marge = 0
if (!isFailure && (rollData.useHeritage || rollData.useTricherie)) {
if (isTricherieHeritage) {
let resTab = [rollData.roll.terms[0].results[0].result, rollData.roll.terms[0].results[1].result, rollData.roll.terms[0].results[2].result]
rollData.diceResult = resTab[0] + "," + resTab[1] + "," + resTab[2]
let subResult = Math.max(Math.max(resTab[0], resTab[1]), resTab[2])
if (resTab[1] == 1) { resTab[1] -= 4 }
if (resTab[2] == 1) { resTab[2] -= 6 }
if (resTab[2] == 2) { resTab[2] -= 7 }
rollData.finalResult = rollData.roll.total - subResult + Math.max(Math.max(resTab[0], resTab[1]), resTab[2])
// Gestion des résultats spéciaux
resTab = resTab.sort()
if ( (resTab[0] == resTab[1]) && (resTab[1] == resTab[2])) {
if ((resTab[0] == resTab[1]) && (resTab[1] == resTab[2])) {
rollData.marge = 7
rollData.isSuccess = true
rollData.isCriticalSuccess = true
rollData.isCriticalSuccess = true
rollData.isBrelan = true
}
if ((resTab[0]+1 == resTab[1]) && (resTab[1]+1 == resTab[2]) ) {
if ((resTab[0] + 1 == resTab[1]) && (resTab[1] + 1 == resTab[2])) {
rollData.marge = 7
rollData.isSuccess = true
rollData.isCriticalSuccess = true
}
if ( rollData.useTricherie) {
rollData.isCriticalSuccess = true
rollData.isSuite = true
}
if (rollData.useTricherie) {
actor.incDecTricherie(-1)
}
if ( rollData.useHeritage) {
if (rollData.useHeritage) {
this.incDecHeritage()
}
} else {
rollData.finalResult = rollData.roll.total
let rollValue = rollData.roll.terms[0].results[0].result
rollData.diceResult = rollData.roll.terms[0].results[0].result
if (rollData.mainDice.includes("d10")) {
if (rollValue == 1) {
rollData.finalResult -= 3 + rollValue // substract 3 and the 1 value that has been added
}
}
if (rollData.mainDice.includes("d12")) {
if (rollValue == 1 || rollValue == 2) {
rollData.finalResult -= 5 + rollValue // Remove also the dice result has it has been added already
}
}
}
//rollData.finalResult = Math.max(rollData.finalResult, 0)
//console.log("Result : ", rollData)
if (rollData.marge == 0 && rollData.sdValue > 0 ) {
rollData.marge = rollData.finalResult - rollData.sdValue
rollData.isSuccess = (rollData.finalResult >= rollData.sdValue)
rollData.isCriticalSuccess = ((rollData.finalResult - rollData.sdValue) >= 7)
rollData.isCriticalFailure = ((rollData.finalResult - rollData.sdValue) <= -7)
}
/* -------------------------------------------- */
static computeArmeDegats(rollData, actor) {
rollData.degatsArme = rollData.arme.system.degats + rollData.marge
if (rollData.arme.system.categorie == "lourde") {
rollData.degatsArme += actor.system.caracteristiques.for.value
}
if (rollData.arme.system.categorie == "blanche" || rollData.arme.system.categorie == "improvise") {
rollData.degatsArme += Math.max(0, actor.system.caracteristiques.for.value - 2)
}
}
/* -------------------------------------------- */
static computeMarge(rollData, seuil) {
if (rollData.marge == 0 && seuil >= 0) {
rollData.marge = rollData.finalResult - seuil
rollData.isSuccess = (rollData.finalResult >= seuil)
rollData.isCriticalSuccess = ((rollData.finalResult - seuil) >= 7)
rollData.isCriticalFailure = ((rollData.finalResult - seuil) <= -7)
}
}
/* -------------------------------------------- */
static async displayUneDefense(rollData, actor, nomDefense, valeurDefense) {
rollData.defenderMode = nomDefense
rollData.defenderValue = valeurDefense
rollData.marge = 0
this.computeMarge(rollData, valeurDefense)
if (rollData.isSuccess) {
this.computeArmeDegats(rollData, actor)
}
this.createChatWithRollMode(rollData.alias, {
content: await renderTemplate(`systems/fvtt-les-heritiers/templates/chat-cc-result.html`, rollData)
}, rollData, "selfroll")
}
/* -------------------------------------------- */
@@ -338,7 +376,7 @@ export class HeritiersUtility {
let actor = this.getActorFromRollData(rollData)
if ( typeof(rollData.pvMalus) != "number" ) {
if (typeof (rollData.pvMalus) != "number") {
ui.notifications.warn("Votre personnage est Moribond(e). Aucun jet autorisé")
return
}
@@ -346,14 +384,16 @@ export class HeritiersUtility {
//rollData.actionImg = "systems/fvtt-les-heritiers/assets/icons/" + actor.system.attributs[rollData.attrKey].labelnorm + ".webp"
rollData.carac = duplicate(actor.system.caracteristiques[rollData.caracKey])
rollData.nbDice = (rollData.useTricherie || rollData.useHeritage) ? 3 : 1
rollData.diceFormula = rollData.nbDice + rollData.mainDice + "kh1"
//console.log("BEFORE COMP", rollData)
if (rollData.useTricherie || rollData.useHeritage) {
rollData.diceFormula = "{1d8, 1d10, 1d12}"
} else {
rollData.diceFormula = "1" + rollData.mainDice + "kh1"
}
let rangValue = 0
if (rollData.rang) {
rangValue = rollData.rang.value
}
}
if (rollData.competence) {
let compmod = (rollData.competence.system.niveau == 0) ? -3 : 0
let specBonus = (rollData.useSpecialite) ? 1 : 0
@@ -369,28 +409,27 @@ export class HeritiersUtility {
await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode"))
rollData.roll = myRoll
console.log(">>>> ", myRoll)
rollData.finalResult = myRoll.total
this.computeResult(actor, rollData)
this.computeMarge(rollData, rollData.sdValue) // Calcul de la marge si seuil présent
if (rollData.mode == "init") {
actor.setFlag("world", "last-initiative", rollData.finalResult)
}
// Compute damages, cf p 187
if (rollData.arme && rollData.isSuccess) {
rollData.degatsArme = rollData.arme.system.degats + rollData.marge
if (rollData.arme.system.categorie == "lourde" ) {
rollData.degatsArme += actor.system.caracteristiques.for.value
}
if (rollData.arme.system.categorie == "blanche" || rollData.arme.system.categorie == "improvise" ) {
rollData.degatsArme += Math.max(0, actor.system.caracteristiques.for.value - 2)
}
this.computeArmeDegats(rollData, actor)
}
this.createChatWithRollMode(rollData.alias, {
content: await renderTemplate(`systems/fvtt-les-heritiers/templates/chat-generic-result.html`, rollData)
}, rollData)
if (rollData.defenderTokenId && rollData.arme && rollData.arme.system.categorie != "trait") {
await this.displayUneDefense(rollData, actor, "Parade", rollData.defenderParade)
await this.displayUneDefense(rollData, actor, "Esquive", rollData.defenderEsquive)
}
}
/* -------------------------------------------- */
@@ -500,7 +539,7 @@ export class HeritiersUtility {
rollId: randomID(16),
rollMode: game.settings.get("core", "rollMode"),
sdList: game.system.lesheritiers.config.seuilsDifficulte,
sdValue: 0,
sdValue: -1,
bonusMalusContext: 0
}
return rollData
@@ -512,18 +551,17 @@ export class HeritiersUtility {
if (target) {
rollData.defenderTokenId = target.id
let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor
rollData.armeDefense = defender.getBestDefenseValue()
rollData.targetVigueur = defender.getVigueur()
if (rollData.armeDefense) {
rollData.difficulte = rollData.armeDefense.system.totalDefensif
} else {
ui.notifications.warn("Aucune arme de défense équipée, difficulté manuelle à positionner.")
}
rollData.defenderName = defender.name
rollData.defenderParade = defender.getCurrentParade()
rollData.defenderEsquive = defender.getCurrentEsquive()
}
}
/* -------------------------------------------- */
static createChatWithRollMode(name, chatOptions, rollData = undefined) {
static createChatWithRollMode(name, chatOptions, rollData = undefined, rollMode = undefined) {
if ( rollMode == undefined) {
rollMode = game.settings.get("core", "rollMode")
}
this.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions, rollData)
}

View File

@@ -78,9 +78,7 @@
.window-app input, .fvtt-les-heritiers .item-form, .sheet header.sheet-header .flex-group-center.flex-compteurs, .sheet header.sheet-header .flex-group-center.flex-fatigue, select, button, .item-checkbox, #sidebar, #players, #navigation #nav-toggle {
font-size: 0.8rem;
}
.fvtt-les-heritiers .sheet-header select option {
/*background-color: rgb(68, 25, 25);*/
}
.fvtt-les-heritiers .sheet-header input, .fvtt-les-heritiers .sheet-header select {
color: rgb(41, 38, 38);
}
@@ -88,6 +86,13 @@
background: rgba(0,0,0,0.75);
}
.page-heading {
color: #151c1f;
}
.heading-link {
color: #151c1f;
}
.window-app.sheet .window-content {
margin: 0;
padding: 0;

View File

@@ -1,7 +1,7 @@
{
"id": "fvtt-les-heritiers",
"description": "Les Héritiers pour FoundryVTT",
"version": "10.0.31",
"version": "10.0.34",
"authors": [
{
"name": "Uberwald/LeRatierBretonnien",
@@ -19,7 +19,7 @@
"gridUnits": "m",
"license": "LICENSE.txt",
"manifest": "https://www.uberwald.me/gitea/public/fvtt-les-heritiers/raw/branch/master/system.json",
"download": "https://www.uberwald.me/gitea/public/fvtt-les-heritiers/archive/fvtt-les-heritiers-10.0.31.zip",
"download": "https://www.uberwald.me/gitea/public/fvtt-les-heritiers/archive/fvtt-les-heritiers-10.0.34.zip",
"languages": [
{
"lang": "fr",

View File

@@ -36,6 +36,7 @@
"habitat": "",
"notes": "",
"statut": "",
"playernotes":"",
"gmnotes": ""
}
},

View File

@@ -50,6 +50,16 @@
<label class="item-field-label-short">Malus</label>
<input type="text" class="item-field-label-short" value="{{pvMalus}}" data-dtype="Number" disabled />
<span>&nbsp;&nbsp;</span>
<select class="item-field-label-medium" type="text" name="system.statutmasque" value="{{system.statutmasque}}" data-dtype="string">
{{#select system.statutmasque}}
{{#each config.statutMasque as |categ cKey|}}
<option value="{{cKey}}">{{categ}}</option>
{{/each}}
{{/select}}
</select>
<span>&nbsp;&nbsp;</span>
<label class="item-field-label-short">Tricherie</label>
<input type="text" class="item-field-label-short" name="system.rang.tricherie.value" value="{{system.rang.tricherie.value}}" data-dtype="Number" />
<input type="text" class="item-field-label-short" name="system.rang.tricherie.max" value="{{system.rang.tricherie.max}}" data-dtype="Number" />

View File

@@ -645,18 +645,28 @@
<div class="medium-editor item-text-long-line">
{{editor description target="system.biodata.description" button=true owner=owner editable=editable}}
</div>
<span>
<h3>Notes diverses</h3>
</span>
<div class="medium-editor item-text-long-line">
{{editor playernotes target="system.biodata.playernotes" button=true owner=owner editable=editable}}
</div>
<span>
<h3>Rêves étranges</h3>
</span>
<div class="medium-editor item-text-long-line">
{{editor revesetranges target="system.biodata.revesetranges" button=true owner=owner editable=editable}}
</div>
<span>
<h3>Secrets découverts</h3>
</span>
<div class="medium-editor item-text-long-line">
{{editor secretsdecouverts target="system.biodata.secretsdecouverts" button=true owner=owner editable=editable}}
</div>
<span>
<h3>Questions en suspens</h3>
</span>

View File

@@ -0,0 +1,34 @@
<div class="chat-message-header">
{{#if actorImg}}
<img class="actor-icon" src="{{actorImg}}" alt="{{alias}}" />
{{/if}}
<h4 class=chat-actor-name>{{alias}}</h4>
</div>
<hr>
{{#if actionImg}}
<div>
<img class="chat-icon" src="{{actionImg}}" alt="{{name}}" />
</div>
{{/if}}
<div class="flexcol">
</div>
<div>
<ul>
<li>Défense de {{defenderName}} : {{defenderMode}} ({{defenderValue}})</li>
{{#if isSuccess}}
<li>Marge : {{marge}}</li>
<li>Degats de l'arme : {{degatsArme}}</li>
{{#if isCriticalSuccess}}
<Li>Critique : Aubaine ou +2 aux dégats ci-dessus</li>
{{/if}}
{{else}}
<li>Echec face à la {{defenderMode}} !</li>
{{/if}}
</ul>
</div>

View File

@@ -1,28 +0,0 @@
<div class="chat-message-header">
{{#if actorImg}}
<img class="actor-icon" src="{{actorImg}}" alt="{{alias}}" />
{{/if}}
<h4 class=chat-actor-name>{{alias}}</h4>
</div>
<hr>
{{#if actionImg}}
<div>
<img class="chat-icon" src="{{actionImg}}" alt="{{name}}" />
</div>
{{/if}}
<div class="flexcol">
</div>
<div>
<ul>
<li>Arme : {{arme.name}} (+{{arme.system.totalDegats}})</li>
<li>Dégats : {{finalResult}}</li>
{{#if targetVigueur}}
<li>Vigueur de la cible : {{targetVigueur}}</li>
<li>Etats Combativité supplémentaires perdus (manuel): {{nbEtatPerdus}} </li>
{{/if}}
</ul>
</div>

View File

@@ -42,12 +42,11 @@
<li>Formule : {{diceFormula}}</li>
<li>Résultat du dé : {{diceResult}} </li>
<li>Total : {{finalResult}} (Marge : {{marge}})</li>
<li>Total : {{finalResult}} {{#if (gt sdValue "-1")}}(Marge : {{marge}}){{/if}}</li>
{{#if sdValue}}
{{#if (gt sdValue "-1")}}
{{#if isSuccess}}
<li class="chat-success">Succés...
<li class="chat-success">Succès...
{{#if arme}}
<li>Dégats : {{degatsArme}}</li>
{{/if}}
@@ -57,6 +56,13 @@
{{/if}}
{{/if}}
{{#if isBrelan}}
<li class="chat-success">Brelan sur 3 dés !</li>
{{/if}}
{{#if isSuite}}
<li class="chat-success">Suite sur 3 dés !</li>
{{/if}}
{{#if isCriticalSuccess}}
<li class="chat-success">Réussite Critique !!!</li>
{{#if arme}}

View File

@@ -71,20 +71,6 @@
<span class="small-label roll-dialog-label">{{pvMalus}}</span>
</div>
{{#if tricherie}}
<div class="flexrow">
<span class="roll-dialog-label">Utiliser 1 point de Tricherie ({{tricherie}}) ?</span>
<input type="checkbox" class="item-field-label-short" id="useTricherie" {{checked useTricherie}}/>
</div>
{{/if}}
{{#if heritage}}
<div class="flexrow">
<span class="roll-dialog-label">Utiliser 1 point d'Heritage ? ({{heritage}})</span>
<input type="checkbox" class="item-field-label-short" id="useHeritage" {{checked useHeritage}}/>
</div>
{{/if}}
<div class="flexrow">
<span class="roll-dialog-label">Bonus/Malus </span>
<select class="roll-dialog-label" id="bonus-malus-context" type="text" value="{{bonusMalusContext}}"