Monnaies et armes à distance #563
@ -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)
|
||||
|
@ -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: '‐'};
|
||||
}
|
||||
|
||||
_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,
|
||||
{
|
||||
|
@ -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',
|
||||
|
9
templates/chat-info-distance.html
Normal file
9
templates/chat-info-distance.html
Normal 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>
|
Loading…
Reference in New Issue
Block a user