Choisir parmi plusieurs cibles #579
@ -35,6 +35,7 @@ import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SHOW_DIC
|
|||||||
import { RdDConfirm } from "./rdd-confirm.js";
|
import { RdDConfirm } from "./rdd-confirm.js";
|
||||||
import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
|
import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
|
||||||
import { RdDRencontre } from "./item-rencontre.js";
|
import { RdDRencontre } from "./item-rencontre.js";
|
||||||
|
import { DialogSelectTarget } from "./dialog-select-target.js";
|
||||||
|
|
||||||
const POSSESSION_SANS_DRACONIC = {
|
const POSSESSION_SANS_DRACONIC = {
|
||||||
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
|
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
|
||||||
@ -2551,18 +2552,17 @@ export class RdDActor extends Actor {
|
|||||||
competence: this.getCompetence(idOrName)
|
competence: this.getCompetence(idOrName)
|
||||||
}
|
}
|
||||||
if (rollData.competence.type == 'competencecreature') {
|
if (rollData.competence.type == 'competencecreature') {
|
||||||
if (rollData.competence.system.iscombat && options.tryTarget) {
|
if (rollData.competence.system.iscombat && options.tryTarget && DialogSelectTarget.hasTargets()) {
|
||||||
const target = RdDCombat.getTarget();
|
DialogSelectTarget.selectOneToken(target => {
|
||||||
if (target) {
|
if (rollData.competence.system.ispossession) {
|
||||||
if (rollData.competence.system.ispossession) {
|
RdDPossession.onAttaquePossession(target, this, rollData.competence)
|
||||||
RdDPossession.onAttaquePossession(target, this, rollData.competence)
|
}
|
||||||
}
|
else {
|
||||||
else {
|
const arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence)
|
||||||
const arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence)
|
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
|
||||||
RdDCombat.rddCombatTarget(this, target).attaque(competence, arme)
|
}
|
||||||
}
|
});
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Transformer la competence de créature
|
// Transformer la competence de créature
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||||
@ -3222,8 +3222,7 @@ export class RdDActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
rollArme(arme) {
|
rollArme(arme) {
|
||||||
const target = RdDCombat.getTarget();
|
if (!DialogSelectTarget.hasTargets()) {
|
||||||
if (!target) {
|
|
||||||
RdDConfirm.confirmer({
|
RdDConfirm.confirmer({
|
||||||
settingConfirmer: "confirmer-combat-sans-cible",
|
settingConfirmer: "confirmer-combat-sans-cible",
|
||||||
content: `<p>Voulez vous faire un jet de compétence ${arme.system.competence} sans choisir de cible valide?
|
content: `<p>Voulez vous faire un jet de compétence ${arme.system.competence} sans choisir de cible valide?
|
||||||
@ -3237,20 +3236,20 @@ export class RdDActor extends Actor {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (RdDCombat.isTargetEntite(target)){
|
DialogSelectTarget.selectOneToken(target => {
|
||||||
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`);
|
if (RdDCombat.isTargetEntite(target)){
|
||||||
return;
|
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`);
|
||||||
}
|
return;
|
||||||
// if (RdDCombat.isTargetEntite(targets[0])) {
|
}
|
||||||
// ui.notifications.warn("Vous ne pouvez pas cibler une entité non incarnée!");
|
|
||||||
// return;
|
|
||||||
// }
|
const competence = this.getCompetence(arme.system.competence)
|
||||||
|
if (competence.system.ispossession) {
|
||||||
|
return RdDPossession.onAttaquePossession(target, this, competence);
|
||||||
|
}
|
||||||
|
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme);
|
||||||
|
})
|
||||||
|
|
||||||
const competence = this.getCompetence(arme.system.competence)
|
|
||||||
if (competence.system.ispossession) {
|
|
||||||
return RdDPossession.onAttaquePossession(target, this, competence);
|
|
||||||
}
|
|
||||||
RdDCombat.rddCombatTarget(this, target).attaque(competence, arme);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
60
module/dialog-select-target.js
Normal file
60
module/dialog-select-target.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
|
||||||
|
export class DialogSelectTarget extends Dialog {
|
||||||
|
static hasTargets() {
|
||||||
|
return (game.user.targets?.size ?? 0) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async selectOneToken(onSelectTarget = target => { }) {
|
||||||
|
if (DialogSelectTarget.hasTargets()) {
|
||||||
|
const targets = game.user.targets.map(it => it);
|
||||||
|
switch (targets.size) {
|
||||||
|
case 0: return;
|
||||||
|
case 1:
|
||||||
|
onSelectTarget(targets[0]);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
const tokens = targets.map(it => { return { id: it.id, name: it.document.name, img: it.document.texture.src ?? it.actor.img ?? 'icons/svg/mystery-man.svg' } })
|
||||||
|
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-select-target.html", {
|
||||||
|
tokens: tokens
|
||||||
|
});
|
||||||
|
new DialogSelectTarget(html, onSelectTarget, targets).render(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(html, onSelectTarget, targets) {
|
||||||
|
const options = {
|
||||||
|
classes: ["rdd-dialog-select-target"],
|
||||||
|
width: 'fit-content',
|
||||||
|
height: 'fit-content',
|
||||||
|
'max-height': 600,
|
||||||
|
'z-index': 99999
|
||||||
|
};
|
||||||
|
const conf = {
|
||||||
|
title: "Choisir une cible",
|
||||||
|
content: html,
|
||||||
|
buttons: {}
|
||||||
|
};
|
||||||
|
super(conf, options);
|
||||||
|
this.onSelectTarget = onSelectTarget;
|
||||||
|
this.targets = targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
html.find("li.select-target").click((event) => {
|
||||||
|
this.targetSelected($(event.currentTarget)?.data("token-id"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
targetSelected(tokenId) {
|
||||||
|
const target = this.targets.find(it => it.id == tokenId);
|
||||||
|
this.close();
|
||||||
|
if (target) {
|
||||||
|
this.onSelectTarget(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { ENTITE_BLURETTE, 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 { DialogSelectTarget } from "./dialog-select-target.js";
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { RdDItemArme } from "./item-arme.js";
|
import { RdDItemArme } from "./item-arme.js";
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
@ -469,17 +470,6 @@ export class RdDCombat {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static rddCombatTarget(attacker, target) {
|
|
||||||
const defender = target?.actor;
|
|
||||||
const defenderTokenId = target?.id;
|
|
||||||
return new RdDCombat(attacker, defender, defenderTokenId, target)
|
|
||||||
}
|
|
||||||
|
|
||||||
static isTargetEntite(target) {
|
|
||||||
return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getTarget() {
|
static getTarget() {
|
||||||
const targets = game.user.targets;
|
const targets = game.user.targets;
|
||||||
@ -488,10 +478,25 @@ export class RdDCombat {
|
|||||||
for (let t of targets) {
|
for (let t of targets) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
case 0:
|
||||||
|
ui.notifications.warn("Vous devez choisir une cible à attaquer!");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
DialogSelectTarget.selectOneToken(t => console.info(`selecte target ${t}`));
|
||||||
ui.notifications.warn("Vous devez choisir une cible (et <strong>une seule</strong>) à attaquer!");
|
ui.notifications.warn("Vous devez choisir une cible (et <strong>une seule</strong>) à attaquer!");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static isTargetEntite(target) {
|
||||||
|
return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static rddCombatTarget(target, attacker) {
|
||||||
|
const defender = target?.actor;
|
||||||
|
const defenderTokenId = target?.id;
|
||||||
|
return new RdDCombat(attacker, defender, defenderTokenId, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -500,6 +505,7 @@ export class RdDCombat {
|
|||||||
let defender = defenderTokenId ? canvas.tokens.get(defenderTokenId)?.actor : undefined;
|
let defender = defenderTokenId ? canvas.tokens.get(defenderTokenId)?.actor : undefined;
|
||||||
let target = undefined
|
let target = undefined
|
||||||
if (!defenderTokenId || !defender) {
|
if (!defenderTokenId || !defender) {
|
||||||
|
console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`);
|
||||||
target = RdDCombat.getTarget()
|
target = RdDCombat.getTarget()
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return;
|
return;
|
||||||
|
@ -332,6 +332,22 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
|
|||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
object-position: 50% 0;
|
object-position: 50% 0;
|
||||||
}
|
}
|
||||||
|
.rdd-dialog-select-target img.select-token-img {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-ms-flex: 0 0 48px;
|
||||||
|
flex: 0 0 48px;
|
||||||
|
height: 48px;
|
||||||
|
width: 48px;
|
||||||
|
border: 0;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
object-fit: cover;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rdd-dialog-select-target li.select-target {
|
||||||
|
vertical-align: baseline;
|
||||||
|
padding: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.dice-img {
|
.dice-img {
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
@ -488,40 +504,40 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
|
|||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.foundryvtt-reve-de-dragon .items-list {
|
.foundryvtt-reve-de-dragon .item-list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 7px 0;
|
margin: 7px 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.foundryvtt-reve-de-dragon .items-list .item-header {
|
.foundryvtt-reve-de-dragon .item-list .item-header {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.foundryvtt-reve-de-dragon .items-list .item {
|
.foundryvtt-reve-de-dragon .item-list .item {
|
||||||
height: 30px;
|
height: 30px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
padding: 3px 0;
|
padding: 3px 0;
|
||||||
border-bottom: 1px solid #BBB;
|
border-bottom: 1px solid #BBB;
|
||||||
}
|
}
|
||||||
|
|
||||||
.foundryvtt-reve-de-dragon .items-list .item .item-image {
|
.foundryvtt-reve-de-dragon .item-list .item .item-image {
|
||||||
-webkit-box-flex: 0;
|
-webkit-box-flex: 0;
|
||||||
-ms-flex: 0 0 24px;
|
-ms-flex: 0 0 24px;
|
||||||
flex: 0 0 24px;
|
flex: 0 0 24px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.foundryvtt-reve-de-dragon .items-list .item img {
|
.foundryvtt-reve-de-dragon .item-list .item img {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.foundryvtt-reve-de-dragon .items-list .item-name {
|
.foundryvtt-reve-de-dragon .item-list .item-name {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.foundryvtt-reve-de-dragon .items-list .item-controls {
|
.foundryvtt-reve-de-dragon .item-list .item-controls {
|
||||||
-webkit-box-flex: 0;
|
-webkit-box-flex: 0;
|
||||||
-ms-flex: 0 0 86px;
|
-ms-flex: 0 0 86px;
|
||||||
flex: 0 0 86px;
|
flex: 0 0 86px;
|
||||||
@ -680,7 +696,7 @@ section.sheet-body{padding: 0.25rem 0.5rem;}
|
|||||||
padding: 0 0 0 0.25rem;
|
padding: 0 0 0 0.25rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
line-height: 2.5rem;
|
line-height: 1.2rem;
|
||||||
border-top: 0 none;
|
border-top: 0 none;
|
||||||
border-bottom: 0 none;
|
border-bottom: 0 none;
|
||||||
color: rgba(52, 52, 52, 0.95);
|
color: rgba(52, 52, 52, 0.95);
|
||||||
@ -862,7 +878,7 @@ ul, li {
|
|||||||
box-shadow: inset 0px 0px 1px #00000096;
|
box-shadow: inset 0px 0px 1px #00000096;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
padding: 0.1rem;
|
padding: 0.1rem;
|
||||||
flex: 1 1 5rem;
|
flex: 1 1 1.5rem;
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"id": "foundryvtt-reve-de-dragon",
|
"id": "foundryvtt-reve-de-dragon",
|
||||||
"title": "Rêve de Dragon",
|
"title": "Rêve de Dragon",
|
||||||
"version": "10.2.7",
|
"version": "10.2.8",
|
||||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.2.7.zip",
|
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.2.8.zip",
|
||||||
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
|
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "10",
|
"minimum": "10",
|
||||||
|
14
templates/dialog-select-target.html
Normal file
14
templates/dialog-select-target.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<form class="rdd-dialog-select-target">
|
||||||
|
<label>Choisir une seule des cibles</label>
|
||||||
|
<hr>
|
||||||
|
<ul class="flexcol item-list alterne-list">
|
||||||
|
{{#each tokens as |token key|}}
|
||||||
|
<li class="select-target item list-item flexrow" data-token-id="{{token.id}}">
|
||||||
|
<img class="select-token-img flex-shrink" src="{{token.img}}" title="{{token.name}}" />
|
||||||
|
<a>
|
||||||
|
<label>{{token.name}}</label>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</form>
|
Loading…
Reference in New Issue
Block a user