Ajout d'informations pour armes à distance

* prise en compte de la taille de la cible
* prise en compte de l'activité
* valeur indicative
This commit is contained in:
Vincent Vandemeulebrouck 2022-10-07 23:28:41 +02:00
parent 4f8406360f
commit 3e17dd9b7e
4 changed files with 82 additions and 21 deletions

View File

@ -139,9 +139,9 @@ export class RdDActor extends Actor {
// Make separate methods for each Actor type (character, npc, etc.) to keep
// things organized.
if (this.type === 'personnage') this._prepareCharacterData(this)
if (this.type === 'creature') this._prepareCreatureData(this)
if (this.type === 'vehicule') this._prepareVehiculeData(this)
if (this.isPersonnage()) this._prepareCharacterData(this)
if (this.isCreature()) this._prepareCreatureData(this)
if (this.isVehicule()) this._prepareVehiculeData(this)
}
/* -------------------------------------------- */
@ -196,6 +196,9 @@ export class RdDActor extends Actor {
isPersonnage() {
return this.type == 'personnage';
}
isVehicule() {
return this.type == 'vehicule';
}
/* -------------------------------------------- */
isHautRevant() {
return this.isPersonnage() && this.system.attributs.hautrevant.value != ""
@ -4107,7 +4110,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async setEffect(statusId, status) {
if (this.isEntite() || this.type == 'vehicule') {
if (this.isEntite() || this.isVehicule()) {
return;
}
console.log("setEffect", statusId, status)

View File

@ -1,5 +1,5 @@
import { ChatUtility } from "./chat-utility.js";
import { ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { Grammar } from "./grammar.js";
import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js";
@ -688,27 +688,75 @@ export class RdDCombat {
}
/* -------------------------------------------- */
verifierDistance( rollData ) {
if ( rollData.competence.system.categorie == "tir" ||
rollData.competence.system.categorie == "lancer" ) {
const defenderToken = canvas.tokens.get(this.defenderTokenId)
let dist = canvas.grid.measureDistances([{ ray: new Ray(_token.center, defenderToken.center) }], { gridSpaces: false })
dist = Number(dist).toPrecision(5)
//let ray = new Ray( {x: _token.x, y: _token.y}, {x: defenderToken.x, y:defenderToken.y} )
let msgPortee = "portée est courte (0)"
if (dist > rollData.arme.system.portee_courte && dist <= rollData.arme.system.portee_moyenne) {
msgPortee = "portée est moyenne (-3)"
} else if (dist > rollData.arme.system.portee_moyenne && dist <= rollData.arme.system.portee_extreme) {
msgPortee = "portée est extrême (-5)"
} else if ( dist > rollData.arme.system.portee_extreme) {
msgPortee = "cible est inateignable"
async proposerAjustementTirLancer( rollData ) {
if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) {
if (this.defender.isEntite([ENTITE_BLURETTE])){
ChatMessage.create( {
content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`,
whisper: ChatMessage.getWhisperRecipients("GM")})
}
else {
const defenderToken = canvas.tokens.get(this.defenderTokenId);
const dist = this.distance(_token, defenderToken)
const portee = this._ajustementPortee(dist, rollData.arme)
const taille = this._ajustementTaille(this.defender)
const activite = this._ajustementMouvement(this.defender)
const total = [portee, taille, activite].map(it=>it.diff).filter(d => !Number.isNaN(d)).reduce(Misc.sum(), 0)
ChatMessage.create({
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html', {
rollData: rollData,
attacker: _token,
defender: defenderToken,
distance: dist,
portee: portee,
taille: taille,
activite: activite,
total: total
}),
whisper: ChatMessage.getWhisperRecipients("GM")
})
}
ChatMessage.create( { content: `<strong>Indication MJ</strong> : La cible est à une distance indicative de : ${dist} mètres. Pour l'arme ${rollData.arme.name}, la ${msgPortee}.`, whisper: ChatMessage.getWhisperRecipients("GM") } )
}
}
distance(t, defenderToken) {
return Number(canvas.grid.measureDistances([{ ray: new Ray(t.center, defenderToken.center) }], { gridSpaces: false })).toFixed(1);
}
_ajustementPortee(dist, arme) {
if (dist <= arme.system.portee_courte) return {msg:"courte", diff:0};
if (dist <= arme.system.portee_moyenne) return {msg: "moyenne" , diff: -3};
if (dist <= arme.system.portee_extreme) return {msg: "extrême", diff:-5};
return {msg: "inatteignable", diff: '&hyphen;'};
}
_ajustementTaille(actor) {
if (actor.isVehicule()) return {msg: "véhicule", diff: 0}
const taille = actor.getCaracByName('TAILLE')?.value ?? 1;
if (taille <= 1) return {msg: "souris", diff: -8};
if (taille <= 3) return {msg: "chat", diff: -4};
if (taille <= 5) return {msg: "chien", diff: -2};
if (taille <= 15) return {msg: "humanoïde", diff: 0};
if (taille <= 20) return {msg: "ogre", diff: 2};
return {msg: "gigantesque", diff: 4};
}
_ajustementMouvement(defender) {
if (defender.getSurprise(true)) return {msg: "immobile (surprise)", diff: 0};
if (game.combat?.combatants.find(it => it.actorId == defender.id)) return {msg: "en mouvement (combat)", diff: -4};
return {msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3};
}
/* -------------------------------------------- */
async attaque(competence, arme) {
// const nonIncarnee = this.defender.isEntite([ENTITE_NONINCARNE])
// const blurette = this.defender.isEntite([ENTITE_BLURETTE])
// if (nonIncarnee || blurette) {
// ChatMessage.create( {
// content: `<strong>La cible est ${nonIncarnee ? 'non incarnée' : 'une blurette'}.
// Il est impossible de l'atteindre.`,
// whisper: ChatMessage.getWhisperRecipients("GM")})
// }
if (!await this.accorderEntite('avant-attaque')) {
return;
}
@ -729,7 +777,7 @@ export class RdDCombat {
if (arme) {
this.attacker.verifierForceMin(arme);
}
this.verifierDistance(rollData)
await this.proposerAjustementTirLancer(rollData)
const dialog = await RdDRoll.create(this.attacker, rollData,
{

View File

@ -241,6 +241,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-description.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html',

View File

@ -0,0 +1,9 @@
<img class="chat-icon" src="{{rollData.arme.img}}" alt="{{rollData.arme.name}}" />
<strong>Ajustement de tir/lancer</strong> proposé de <strong>{{total}}</strong>
<ul>
<li>{{defender.name}} est à une distance indicative de {{distance}} mètres.</li>
{{log defender}}
<li>Portée {{portee.msg}} pour l'arme {{rollData.arme.name}} : {{portee.diff}}</li>
<li>De taille {{taille.msg}}: {{taille.diff}}</li>
<li>Mouvement {{activite.msg}}: {{activite.diff}}</li>
</ul>