From be73c51b97fdbbdaf99347b2e7dc20a7984d1645 Mon Sep 17 00:00:00 2001 From: sladecraven Date: Sat, 5 Dec 2020 21:24:31 +0100 Subject: [PATCH] 43 Init et attaque vie HUD ou fiche de perso --- module/actor-sheet.js | 27 ++++++++++++++++++++------- module/actor.js | 35 ++++++++++++++++++++++++++--------- module/rdd-token-hud.js | 34 ++++++++++++++++++++++------------ module/rdd-utility.js | 15 ++++++++------- styles/simple.css | 25 +++++++++++++++++++------ 5 files changed, 95 insertions(+), 41 deletions(-) diff --git a/module/actor-sheet.js b/module/actor-sheet.js index a4aef1ed..e050bacf 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -74,18 +74,21 @@ export class RdDActorSheet extends ActorSheet { // To avoid armour and so on... data.data.combat = duplicate( RdDUtility.checkNull(data.itemsByType['arme'])); - data.data.combat = RdDUtility.finalizeArmeList( data.data.combat, data.competenceByCategory ); + data.data.combat = RdDUtility.finalizeArmeList( data.data.combat, data.itemsByType.competence, data.data.carac ); if (data.competenceByCategory && data.competenceByCategory.melee) { //Specific case for Esquive and Corps à Corps for ( const melee of data.competenceByCategory.melee ) { if (melee.name == "Esquive") - data.data.combat.push( { name: "Esquive", data: { niveau: melee.data.niveau, description: "", force: 6, competence: "Esquive", dommages: 0} } ); - if (melee.name == "Corps à corps") - data.data.combat.push( { name: "Corps à corps", data: { niveau: melee.data.niveau, description: "", force: 6, competence: "Corps à corps", dommages: data.data.attributs.plusdom.value } } ); + data.data.combat.push( { name: "Esquive", data: { niveau: melee.data.niveau, description: "", force: 6, initiative: "-", competence: "Esquive", dommages: 0} } ); + if (melee.name == "Corps à corps") { + let cc_init = "1d6" + melee.data.niveau + "+" + Math.ceil(data.data.carac['melee'].value / 2 ); + data.data.combat.push( { name: "Corps à corps", data: { niveau: melee.data.niveau, description: "", force: 6, initiative: cc_init, competence: "Corps à corps", dommages: data.data.attributs.plusdom.value } } ); + } } } - + this.armesList = duplicate(data.data.combat); + data.data.carac.taille.isTaille = true; // To avoid button link; data.data.nbLegeres = this.actor.countBlessures(data.data.blessures.legeres.liste ); data.data.nbGraves = this.actor.countBlessures(data.data.blessures.graves.liste ); @@ -263,14 +266,24 @@ export class RdDActorSheet extends ActorSheet { // Points de reve actuel html.find('.ptreve-actuel a').click((event) => { this.actor.rollCarac( 'reveActuel' ); - }); - + }); // Roll Weapon1 html.find('.arme-label a').click((event) => { let armeName = event.currentTarget.text; let competenceName = event.currentTarget.attributes['data-competence-name'].value; this.actor.rollArme( armeName, competenceName); }); + // Initiative pour l'arme + html.find('.arme-initiative a').click((event) => { + let combatant = game.combat.data.combatants.find(c => c.actor.data._id == this.actor.data._id ); + if ( combatant ) { + let armeName = event.currentTarget.attributes['data-arme-name'].value; + let arme = this.armesList.find( a => a.name == armeName); + RdDUtility.rollInitiativeCompetence( combatant._id, arme); + } else { + ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat."); + } + }); // Display TMR, normal html.find('#visu-tmr').click((event) => { this.actor.displayTMR( "visu"); diff --git a/module/actor.js b/module/actor.js index 2562f131..939df99f 100644 --- a/module/actor.js +++ b/module/actor.js @@ -163,6 +163,13 @@ export class RdDActor extends Actor { } } + /* -------------------------------------------- */ + computeDeteriorationArme( rollData ) { + if ( rollData.arme && rollData.attackerRoll) { // C'est une parade + + } + } + /* -------------------------------------------- */ async continueRoll(rollData, attacker = undefined) { let rolled = rollData.rolled; @@ -198,6 +205,7 @@ export class RdDActor extends Actor { // In case of fight, replace the message per dommages + localization. it indicates if result is OK or not if (rollData.attackerRoll) { // Defense case ! if (rolled.isSign || (!rollData.needSignificative && rolled.isSuccess)) { + this.computeDeteriorationArme( rollData ); explications += "
Attaque parée/esquivée !"; } else { explications += "
Esquive/Parade échouée, encaissement !"; @@ -277,6 +285,7 @@ export class RdDActor extends Actor { } } + /* -------------------------------------------- */ static _calculMortaliteEncaissement(rollData, target) { const mortalite = target.actor.isEntiteCauchemar() ? "cauchemar" : (rollData.mortalite ? rollData.mortalite : "mortel"); console.log("Mortalité : ", mortalite, target.actor.data.type); @@ -410,6 +419,7 @@ export class RdDActor extends Actor { } } + /* -------------------------------------------- */ _retrograderBlessure(type, blessure, blessuresMoindres) { if (type != "legere") { @@ -423,10 +433,12 @@ export class RdDActor extends Actor { return true; } + /* -------------------------------------------- */ _supprimerBlessure(blessure) { mergeObject(blessure, { "active": false, "premiers_soins": 0, "soins_complets": 0, "jours": 0, "localisation": "" }); } + /* -------------------------------------------- */ async _recupererVie(message) { let blessures = [].concat(this.data.data.blessures.legeres.liste).concat(this.data.data.blessures.graves.liste).concat(this.data.data.blessures.critiques.liste); let nbBlessures = blessures.filter(b => b.active); @@ -452,7 +464,8 @@ export class RdDActor extends Actor { } } } - + + /* -------------------------------------------- */ async _jetRecuperationConstitution(bonusSoins, message = undefined) { let difficulte = Misc.toInt(bonusSoins) + Math.min(0, this.data.data.sante.vie.value - this.data.data.sante.vie.max); let rolled = await RdDResolutionTable.roll(this.data.data.carac.constitution.value, difficulte); @@ -462,7 +475,7 @@ export class RdDActor extends Actor { return rolled; } - + /* -------------------------------------------- */ async remiseANeuf() { let message = { whisper: ChatUtility.getWhisperRecipientsAndGMs( this.name ), @@ -568,6 +581,8 @@ export class RdDActor extends Actor { } } } + + /* -------------------------------------------- */ async retourSeuilDeReve(message) { const seuil = this.data.data.reve.seuil.value; const reveActuel = this.getReveActuel(); @@ -733,10 +748,6 @@ export class RdDActor extends Actor { contenu.splice(index, 1); index = contenu.indexOf(itemId); } - //console.log("REMOVED: ", itemId, contenu ); - //let newContenu = conteneur.data.data.contenu.filter( function(value, index, arr) { return value != itemId } ); - //console.log("Suppression du conteneur2", conteneurId, itemId, newContenu); - //let update = {_id: conteneurId, "data.contenu": newContenu }; await this.updateEmbeddedEntity("OwnedItem", data2use); } } @@ -1330,6 +1341,7 @@ export class RdDActor extends Actor { } } + /* -------------------------------------------- */ getTarget() { if (game.user.targets && game.user.targets.size == 1) { for (let target of game.user.targets) { @@ -1363,13 +1375,13 @@ export class RdDActor extends Actor { if ( update.data.deterioration >= 10) { update.data.deterioration = 0; if ( update.data.protection.toString().length == 1 ) - update.data.protection = "d"+update.data.protection+"-0"; + update.data.protection = "1d"+update.data.protection+"-0"; else { let regex = /d\(d+)\-(\d+)/g; let res = regex.exec( update.data.protection ); - update.data.protection = "d"+res[1]+"-"+(parseInt(res[2])+1); + update.data.protection = "1d"+res[1]+"-"+(parseInt(res[2])+1); } - /* TODO - POST chat message */ + ChatMessage.create( {content: "Détérioration d'armure: " + update.data.protection } ); } this.updateEmbeddedEntity("OwnedItem", update); } @@ -1442,6 +1454,7 @@ export class RdDActor extends Actor { } + /* -------------------------------------------- */ /* -- entites -- */ /* retourne true si on peut continuer, false si on ne peut pas continuer */ async targetEntiteNonAccordee(target, when='avant-encaissement') @@ -1453,6 +1466,7 @@ export class RdDActor extends Actor { return false; } + /* -------------------------------------------- */ async accorder(entite, when = 'avant-encaissement') { if (when != game.settings.get("foundryvtt-reve-de-dragon", "accorder-entite-cauchemar") @@ -1480,11 +1494,13 @@ export class RdDActor extends Actor { return rolled.isSuccess; } + /* -------------------------------------------- */ isEntiteCauchemar() { return this.data.type == 'entite'; } + /* -------------------------------------------- */ isEntiteCauchemarAccordee(attaquant) { if (!this.isEntiteCauchemar()) { return true; } @@ -1492,6 +1508,7 @@ export class RdDActor extends Actor { return (resonnance.actors.find(it => it == attaquant._id)); } + /* -------------------------------------------- */ async setEntiteReveAccordee(attaquant) { if (!this.isEntiteCauchemar()) { diff --git a/module/rdd-token-hud.js b/module/rdd-token-hud.js index 312bb9e4..e0519cc2 100644 --- a/module/rdd-token-hud.js +++ b/module/rdd-token-hud.js @@ -23,30 +23,40 @@ export class RdDTokenHud { // Get combatant stuff let combatant = game.combat.data.combatants.find(c => c.tokenId == token.data._id ); if ( combatant ) { - // Create space for Hud Extensions next to combat icon - let divTokenHudExt = '
'; - html.find('.control-icon.combat').wrap(divTokenHudExt); - let armesList = RdDUtility.buildArmeList( combatant ); - let htmlList = ""; + // Create space for Hud Extensions next to combat icon + let htmlInit = '
'; + let htmlCombat = '
'; console.log("Token !!!", combatant, armesList); for( let armeIndex=0; armeIndex'; - htmlList += '
'; + htmlInit += '
'; + htmlInit += '
'; + if ( !arme.data.initOnly) { + htmlCombat += '
'; + htmlCombat += '
'; + } } - let hudInitiative = $(htmlList); - //let hudInitiative = $('
' + Dague + '
'); - //let hudInitiative = $('
Dague
'); + htmlInit += "
"; + htmlCombat += "
"; + let hudInitiative = $(htmlInit); html.find('.control-icon.combat').after(hudInitiative); // Add Initiative and Agility token tip - // Add interactions for Initiative and Agility + let hudCombat = $(htmlCombat); + html.find('.control-icon.combat').after(hudCombat); // Add Initiative and Agility token tip + + // Add interactions for Initiative hudInitiative.find('label').click(async (event) => { let armeIndex = event.currentTarget.attributes['data-arme-id'].value; let combatantId = event.currentTarget.attributes['data-combatant-id'].value; let arme = armesList[armeIndex]; - console.log("CLICKED !", armeIndex, arme); RdDUtility.rollInitiativeCompetence( combatantId, arme ); }); + // Add interactions for Combat + hudCombat.find('label').click(async (event) => { + let armeIndex = event.currentTarget.attributes['data-arme-id'].value; + let arme = armesList[armeIndex]; + actor.rollArme( arme.name, arme.data.competence); + }); } } } \ No newline at end of file diff --git a/module/rdd-utility.js b/module/rdd-utility.js index dec89e86..d35ff7c1 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -403,19 +403,20 @@ export class RdDUtility { /* -------------------------------------------- */ /** Retourne une liste triée d'armes avec le split arme1 main / arme 2 main */ - static finalizeArmeList( armeList, competenceByCategory ) { + static finalizeArmeList( armeList, competenceList, carac ) { // Gestion des armes 1/2 mains let arme2mains = []; // Tableau contenant la duplication des armes 1m/2m for (const arme of armeList) { + let comp = competenceList.find(c => c.name == arme.data.competence); + arme.data.initiative = "1d6+" + arme.data.niveau + "+" + Math.ceil(carac[comp.data.defaut_carac].value/2); // Dupliquer les armes pouvant être à 1 main et 2 mains en patchant la compétence if (arme.data.unemain && arme.data.deuxmains) { let arme2main = duplicate(arme); arme2main.data.dommages = arme2main.data.dommages.split("/")[1]; // Existence temporaire uniquement dans la liste des armes, donc OK arme2main.data.competence = arme2main.data.competence.replace(" 1 main", " 2 mains"); // Replace ! - for ( const melee of competenceByCategory.melee ) { - if (melee.name == arme2main.data.competence ) - arme2main.data.niveau = melee.data.niveau - } + let comp = competenceList.find(c => c.name == arme2main.data.competence); + arme2main.data.niveau = comp.data.niveau; + arme2main.data.initiative = "1d6+" + arme2main.data.niveau + "+" + Math.ceil(carac[comp.data.defaut_carac].value/2); arme2mains.push(arme2main); } } @@ -782,9 +783,9 @@ export class RdDUtility { // Force corps à corps et Draconic let cc = RdDUtility.findCompetence( combatant.actor.data.items, "Corps à corps"); armesList.push( { name: "Corps à corps", data: { niveau: cc.data.niveau, description: "", force: 6, competence: "Corps à corps", dommages: combatant.actor.data.data.attributs.plusdom.value } } ); - armesList.push( { name: "Draconic", data: { competence: "Draconic" } } ); + armesList.push( { name: "Draconic", data: { initOnly: true, competence: "Draconic" } } ); } - armesList.push( { name: "Autre action", data: { competence: "Autre action" } } ); + armesList.push( { name: "Autre action", data: { initOnly: true, competence: "Autre action" } } ); return armesList; } diff --git a/styles/simple.css b/styles/simple.css index afd0b880..753d3317 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -638,14 +638,27 @@ ul, li { font-weight: 600; } .tokenhudext.right { - justify-content: flex-start; + justify-content: flex-start; + flex-direction: column; + position: absolute; + top: 2.75rem; + right: -6rem; +} +.tokenhudext.rightright { + justify-content: flex-start; + flex-direction: column; + position: absolute; + top: 2.75rem; + right: -13rem; } .control-icon.tokenhudicon { - width: fit-content; - min-width: 42px; - flex-basis: auto; - padding: 0 8px; - margin: 8px 0px; + width: fit-content; + height: fit-content; + min-width: 6rem; + flex-basis: auto; + padding: 0; + line-height: 1rem; + margin: 0.25rem; } .control-icon.tokenhudicon.right { margin-left: 8px;