43 Init et attaque vie HUD ou fiche de perso

This commit is contained in:
sladecraven 2020-12-05 21:24:31 +01:00
parent 72b3a96354
commit be73c51b97
5 changed files with 95 additions and 41 deletions

View File

@ -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");

View File

@ -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 += "<br><strong>Attaque parée/esquivée !</strong>";
} else {
explications += "<br><strong>Esquive/Parade échouée, encaissement !</strong>";
@ -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()) {

View File

@ -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 = '<div class="tokenhudext right">';
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 = '<div class="tokenhudext right">';
let htmlCombat = '<div class="tokenhudext rightright">';
console.log("Token !!!", combatant, armesList);
for( let armeIndex=0; armeIndex<armesList.length; armeIndex++) {
let arme = armesList[armeIndex];
htmlList += '<div class="control-icon tokenhudicon right" title="'+ arme.name +'">';
htmlList += '<label class="hud-text-small" data-combatant-id="'+combatant._id+'" data-arme-id="'+armeIndex+'"></i>'+arme.name+'</label></div>';
htmlInit += '<div class="control-icon tokenhudicon right" title="'+ arme.name +'">';
htmlInit += '<label class="hud-text-small" data-combatant-id="'+combatant._id+'" data-arme-id="'+armeIndex+'"></i>I:'+arme.name+'</label></div>';
if ( !arme.data.initOnly) {
htmlCombat += '<div class="control-icon tokenhudicon right" title="'+ arme.name +'">';
htmlCombat += '<label class="hud-text-small" data-combatant-id="'+combatant._id+'" data-arme-id="'+armeIndex+'"></i>C:'+arme.name+'</label></div>';
}
}
let hudInitiative = $(htmlList);
//let hudInitiative = $('<div class="control-icon tokenhudicon right" title="' + TooltipInitiative + '"><i class="fas fa-spinner"></i> ' + Dague + '</div>');
//let hudInitiative = $('<div class="control-icon tokenhudicon right" title="Dague"><i class="fas fa-spinner"></i>Dague</div>');
htmlInit += "</div>";
htmlCombat += "</div>";
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);
});
}
}
}

View File

@ -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;
}

View File

@ -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;