Choisir parmi plusieurs cibles #579

Merged
uberwald merged 3 commits from VincentVk/foundryvtt-reve-de-dragon:v10 into v10 2022-11-23 08:24:18 +01:00
6 changed files with 144 additions and 49 deletions

View File

@ -35,6 +35,7 @@ import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SHOW_DIC
import { RdDConfirm } from "./rdd-confirm.js";
import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
import { RdDRencontre } from "./item-rencontre.js";
import { DialogSelectTarget } from "./dialog-select-target.js";
const POSSESSION_SANS_DRACONIC = {
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
@ -2551,18 +2552,17 @@ export class RdDActor extends Actor {
competence: this.getCompetence(idOrName)
}
if (rollData.competence.type == 'competencecreature') {
if (rollData.competence.system.iscombat && options.tryTarget) {
const target = RdDCombat.getTarget();
if (target) {
if (rollData.competence.system.ispossession) {
RdDPossession.onAttaquePossession(target, this, rollData.competence)
}
else {
const arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence)
RdDCombat.rddCombatTarget(this, target).attaque(competence, arme)
}
return;
}
if (rollData.competence.system.iscombat && options.tryTarget && DialogSelectTarget.hasTargets()) {
DialogSelectTarget.selectOneToken(target => {
if (rollData.competence.system.ispossession) {
RdDPossession.onAttaquePossession(target, this, rollData.competence)
}
else {
const arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence)
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
}
});
return;
}
// Transformer la competence de créature
RdDItemCompetenceCreature.setRollDataCreature(rollData)
@ -3222,8 +3222,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
rollArme(arme) {
const target = RdDCombat.getTarget();
if (!target) {
if (!DialogSelectTarget.hasTargets()) {
RdDConfirm.confirmer({
settingConfirmer: "confirmer-combat-sans-cible",
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;
}
if (RdDCombat.isTargetEntite(target)){
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;
// }
DialogSelectTarget.selectOneToken(target => {
if (RdDCombat.isTargetEntite(target)){
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`);
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);
}
/* -------------------------------------------- */

View 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);
}
}
}

View File

@ -1,5 +1,6 @@
import { ChatUtility } from "./chat-utility.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 { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js";
@ -469,17 +470,6 @@ export class RdDCombat {
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() {
const targets = game.user.targets;
@ -488,10 +478,25 @@ export class RdDCombat {
for (let t of targets) {
return t;
}
case 0:
ui.notifications.warn("Vous devez choisir une cible à attaquer!");
break;
default:
DialogSelectTarget.selectOneToken(t => console.info(`selecte target ${t}`));
ui.notifications.warn("Vous devez choisir une cible (et <strong>une seule</strong>) à attaquer!");
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 target = undefined
if (!defenderTokenId || !defender) {
console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`);
target = RdDCombat.getTarget()
if (!target) {
return;

View File

@ -332,6 +332,22 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
object-fit: cover;
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 {
border-width: 0;
@ -488,40 +504,40 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
text-shadow: none;
}
.foundryvtt-reve-de-dragon .items-list {
.foundryvtt-reve-de-dragon .item-list {
list-style: none;
margin: 7px 0;
padding: 0;
overflow-y: auto;
}
.foundryvtt-reve-de-dragon .items-list .item-header {
.foundryvtt-reve-de-dragon .item-list .item-header {
font-weight: bold;
}
.foundryvtt-reve-de-dragon .items-list .item {
.foundryvtt-reve-de-dragon .item-list .item {
height: 30px;
line-height: 24px;
padding: 3px 0;
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;
-ms-flex: 0 0 24px;
flex: 0 0 24px;
margin-right: 5px;
}
.foundryvtt-reve-de-dragon .items-list .item img {
.foundryvtt-reve-de-dragon .item-list .item img {
display: block;
}
.foundryvtt-reve-de-dragon .items-list .item-name {
.foundryvtt-reve-de-dragon .item-list .item-name {
margin: 0;
}
.foundryvtt-reve-de-dragon .items-list .item-controls {
.foundryvtt-reve-de-dragon .item-list .item-controls {
-webkit-box-flex: 0;
-ms-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;
text-align: center;
text-transform: uppercase;
line-height: 2.5rem;
line-height: 1.2rem;
border-top: 0 none;
border-bottom: 0 none;
color: rgba(52, 52, 52, 0.95);
@ -862,7 +878,7 @@ ul, li {
box-shadow: inset 0px 0px 1px #00000096;
border-radius: 0.25rem;
padding: 0.1rem;
flex: 1 1 5rem;
flex: 1 1 1.5rem;
display: flex !important;
align-items: center !important;
}

View File

@ -1,8 +1,8 @@
{
"id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon",
"version": "10.2.7",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.2.7.zip",
"version": "10.2.8",
"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",
"compatibility": {
"minimum": "10",

View 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>