forked from public/foundryvtt-reve-de-dragon
		
	Merge pull request 'Corrections des TMRs et des Statuis' (#554) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#554
This commit is contained in:
		| @@ -41,7 +41,8 @@ | |||||||
|     "TypeOmbre": "Ombre de Thanatos", |     "TypeOmbre": "Ombre de Thanatos", | ||||||
|     "TypeSouffle": "Souffle de Dragon", |     "TypeSouffle": "Souffle de Dragon", | ||||||
|     "TypeTete": "Tête de Dragon", |     "TypeTete": "Tête de Dragon", | ||||||
|     "TypePossession": "Possession" |     "TypePossession": "Possession", | ||||||
|  |     "TypeSortreserve": "Sort en réserve" | ||||||
|   }, |   }, | ||||||
|   "EFFECT": { |   "EFFECT": { | ||||||
|     "StatusStunned": "Sonné", |     "StatusStunned": "Sonné", | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ import { DialogSplitItem } from "./dialog-split-item.js"; | |||||||
| import { ReglesOptionelles } from "./regles-optionelles.js"; | import { ReglesOptionelles } from "./regles-optionelles.js"; | ||||||
| import { DialogRepos } from "./dialog-repos.js"; | import { DialogRepos } from "./dialog-repos.js"; | ||||||
| import { RdDSheetUtility } from "./rdd-sheet-utility.js"; | import { RdDSheetUtility } from "./rdd-sheet-utility.js"; | ||||||
| import { TMRUtility } from "./tmr-utility.js"; | import { STATUSES } from "./status-effects.js"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RdDActorSheet extends ActorSheet { | export class RdDActorSheet extends ActorSheet { | ||||||
| @@ -100,8 +100,7 @@ export class RdDActorSheet extends ActorSheet { | |||||||
|     formData.difficultesLibres = CONFIG.RDD.difficultesLibres; |     formData.difficultesLibres = CONFIG.RDD.difficultesLibres; | ||||||
|  |  | ||||||
|     formData.hautreve = { |     formData.hautreve = { | ||||||
|       isDemiReve: this.actor.getEffectByLabel("Demi-rêve"), |       isDemiReve: this.actor.getEffect(STATUSES.StatusDemiReve), | ||||||
|       sortsReserve: formData.system.reve.reserve.list, |  | ||||||
|       rencontres: duplicate(formData.system.reve.rencontre.list), |       rencontres: duplicate(formData.system.reve.rencontre.list), | ||||||
|       casesTmr: formData.itemsByType.casetmr, |       casesTmr: formData.itemsByType.casetmr, | ||||||
|       cacheTMR: this.actor.isTMRCache() |       cacheTMR: this.actor.isTMRCache() | ||||||
| @@ -184,19 +183,6 @@ export class RdDActorSheet extends ActorSheet { | |||||||
|       const item = this.actor.getObjet(li.data("item-id")); |       const item = this.actor.getObjet(li.data("item-id")); | ||||||
|       RdDUtility.confirmerSuppressionItem(this, item, li); |       RdDUtility.confirmerSuppressionItem(this, item, li); | ||||||
|     }); |     }); | ||||||
|     html.find('.sort-reserve-delete').click(async event => { |  | ||||||
|       const li = RdDSheetUtility.getEventElement(event); |  | ||||||
|       const index = li.data('index'); |  | ||||||
|       const sortReserve = this.actor.system.reve.reserve.list[index]; |  | ||||||
|       RdDUtility.confirmerSuppression(this, li, { |  | ||||||
|         supprimer: `le sort en réserve ${sortReserve.sort.name} en ${TMRUtility.getTMR(sortReserve.coord).label}`, |  | ||||||
|         deleteLabel: "Supprimer le sort en réserve", |  | ||||||
|         onDelete: () => { |  | ||||||
|           console.log("Delete : ", sortReserve.name); |  | ||||||
|           this.actor.deleteSortReserveKey(index); |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     }); |  | ||||||
|     html.find('.item-vendre').click(async event => { |     html.find('.item-vendre').click(async event => { | ||||||
|       const item = RdDSheetUtility.getItem(event, this.actor); |       const item = RdDSheetUtility.getItem(event, this.actor); | ||||||
|       item?.proposerVente(); |       item?.proposerVente(); | ||||||
| @@ -375,11 +361,15 @@ export class RdDActorSheet extends ActorSheet { | |||||||
|       await DialogRepos.create(this.actor); |       await DialogRepos.create(this.actor); | ||||||
|     }); |     }); | ||||||
|     html.find('.delete-active-effect').click(async event => { |     html.find('.delete-active-effect').click(async event => { | ||||||
|       let id = $(event.currentTarget).parents(".active-effect").data('id'); |       if (game.user.isGM) { | ||||||
|       this.actor.enleverActiveEffectById(id); |         let effect = $(event.currentTarget).parents(".active-effect").data('effect'); | ||||||
|  |         this.actor.removeEffect(effect); | ||||||
|  |       } | ||||||
|     }); |     }); | ||||||
|     html.find('.enlever-tous-effets').click(async event => { |     html.find('.enlever-tous-effets').click(async event => { | ||||||
|       this.actor.enleverTousLesEffets(); |       if (game.user.isGM) { | ||||||
|  |         this.actor.enleverTousLesEffets(); | ||||||
|  |       } | ||||||
|     }); |     }); | ||||||
|     html.find('.conteneur-name a').click(async event => { |     html.find('.conteneur-name a').click(async event => { | ||||||
|       RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event)); |       RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event)); | ||||||
|   | |||||||
							
								
								
									
										112
									
								
								module/actor.js
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								module/actor.js
									
									
									
									
									
								
							| @@ -17,7 +17,7 @@ import { RdDAudio } from "./rdd-audio.js"; | |||||||
| import { RdDItemCompetence } from "./item-competence.js"; | import { RdDItemCompetence } from "./item-competence.js"; | ||||||
| import { RdDItemArme } from "./item-arme.js"; | import { RdDItemArme } from "./item-arme.js"; | ||||||
| import { RdDAlchimie } from "./rdd-alchimie.js"; | import { RdDAlchimie } from "./rdd-alchimie.js"; | ||||||
| import { StatusEffects } from "./status-effects.js"; | import { STATUSES, StatusEffects } from "./status-effects.js"; | ||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||||
| import { RdDItemSigneDraconique } from "./item-signedraconique.js"; | import { RdDItemSigneDraconique } from "./item-signedraconique.js"; | ||||||
| import { ReglesOptionelles } from "./regles-optionelles.js"; | import { ReglesOptionelles } from "./regles-optionelles.js"; | ||||||
| @@ -52,8 +52,6 @@ const POSSESSION_SANS_DRACONIC = { | |||||||
| export class RdDActor extends Actor { | export class RdDActor extends Actor { | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static init() { |   static init() { | ||||||
|     Hooks.on("deleteActiveEffect", (effect, options, userId) => RdDActor.getParentActor(effect)?.onDeleteActiveEffect(effect, options)); |  | ||||||
|  |  | ||||||
|     Hooks.on("preUpdateItem", (item, change, options, id) => RdDActor.getParentActor(item)?.onPreUpdateItem(item, change, options, id)); |     Hooks.on("preUpdateItem", (item, change, options, id) => RdDActor.getParentActor(item)?.onPreUpdateItem(item, change, options, id)); | ||||||
|     Hooks.on("createItem", (item, options, id) => RdDActor.getParentActor(item)?.onCreateItem(item, options, id)); |     Hooks.on("createItem", (item, options, id) => RdDActor.getParentActor(item)?.onCreateItem(item, options, id)); | ||||||
|     Hooks.on("deleteItem", (item, options, id) => RdDActor.getParentActor(item)?.onDeleteItem(item, options, id)); |     Hooks.on("deleteItem", (item, options, id) => RdDActor.getParentActor(item)?.onDeleteItem(item, options, id)); | ||||||
| @@ -418,31 +416,9 @@ export class RdDActor extends Actor { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async deleteSortReserve(sortReserve) { |  | ||||||
|     let reserve = duplicate(this.system.reve.reserve); |  | ||||||
|     let tmr = TMRUtility.getTMR(sortReserve.coord); |  | ||||||
|     let index = reserve.list.findIndex(tmr.type == 'fleuve' |  | ||||||
|       ? sort => (TMRUtility.getTMR(sort.coord).type == 'fleuve' && sort.sort.name == sortReserve.sort.name) |  | ||||||
|       : sort => (sort.coord == sortReserve.coord && sort.sort.name == sortReserve.sort.name) |  | ||||||
|     ); |  | ||||||
|     if (index >= 0) { |  | ||||||
|       reserve.list.splice(index, 1); |  | ||||||
|       await this.update({ "system.reve.reserve": reserve }); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async deleteSortReserveKey(index) { |  | ||||||
|     let reserve = duplicate(this.system.reve.reserve); |  | ||||||
|     if (index >= 0) { |  | ||||||
|       reserve.list.splice(index, 1); |  | ||||||
|       await this.update({ "system.reve.reserve": reserve }, { renderSheet: false }); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   getSurprise(isCombat = undefined) { |   getSurprise(isCombat = undefined) { | ||||||
|     let niveauSurprise = this.getActiveEffects() |     let niveauSurprise = this.getEffects() | ||||||
|       .map(effect => StatusEffects.valeurSurprise(effect, isCombat)) |       .map(effect => StatusEffects.valeurSurprise(effect, isCombat)) | ||||||
|       .reduce(Misc.sum(), 0); |       .reduce(Misc.sum(), 0); | ||||||
|     if (niveauSurprise > 1) { |     if (niveauSurprise > 1) { | ||||||
| @@ -856,10 +832,13 @@ export class RdDActor extends Actor { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async sortMisEnReserve(rollData, sort) { |   async sortMisEnReserve(sort, draconic, coord, ptreve) { | ||||||
|     let reserve = duplicate(this.system.reve.reserve.list); |     await this.createEmbeddedDocuments("Item", [{ | ||||||
|     reserve.push({ coord: rollData.tmr.coord, sort: sort, draconic: duplicate(rollData.competence) }); |         type: 'sortreserve', | ||||||
|     await this.update({ "system.reve.reserve.list": reserve }); |         name: sort.name, | ||||||
|  |         img: sort.img, | ||||||
|  |         system: { sortid: sort.id, draconic: (draconic ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' } }], | ||||||
|  |         { renderSheet: false}); | ||||||
|     this.currentTMR.updateTokens(); |     this.currentTMR.updateTokens(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1140,11 +1119,11 @@ export class RdDActor extends Actor { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async deleteAllConteneur(itemId) { |   async deleteAllConteneur(itemId, options) { | ||||||
|     let list = []; |     let list = []; | ||||||
|     list.push({ id: itemId, conteneurId: undefined }); // Init list |     list.push({ id: itemId, conteneurId: undefined }); // Init list | ||||||
|     this.buildSubConteneurObjetList(itemId, list); |     this.buildSubConteneurObjetList(itemId, list); | ||||||
|     await this.deleteEmbeddedDocuments('Item', list.map(it => it.id)); |     await this.deleteEmbeddedDocuments('Item', list.map(it => it.id), options); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -1606,12 +1585,12 @@ export class RdDActor extends Actor { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   getSonne() { |   getSonne() { | ||||||
|     return this.getEffectByLabel("EFFECT.StatusStunned"); |     return this.getEffect(STATUSES.StatusStunned); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async finDeRound(options = { terminer: false }) { |   async finDeRound(options = { terminer: false }) { | ||||||
|     for (let effect of this.getActiveEffects()) { |     for (let effect of this.getEffects()) { | ||||||
|       if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) { |       if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) { | ||||||
|         if (effect.system.origin) { |         if (effect.system.origin) { | ||||||
|           await effect.update({ 'disabled': true }); |           await effect.update({ 'disabled': true }); | ||||||
| @@ -1640,7 +1619,7 @@ export class RdDActor extends Actor { | |||||||
|       ui.notifications.info("Le personnage est hors combat, il ne reste donc pas sonné"); |       ui.notifications.info("Le personnage est hors combat, il ne reste donc pas sonné"); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     await this.setStatusEffect("EFFECT.StatusStunned", sonne); |     await this.setEffect(STATUSES.StatusStunned, sonne); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -1793,7 +1772,7 @@ export class RdDActor extends Actor { | |||||||
|     } |     } | ||||||
|     await this.update({ "system.sante": sante }) |     await this.update({ "system.sante": sante }) | ||||||
|     if (this.isDead()) { |     if (this.isDead()) { | ||||||
|       await this.setStatusEffect("EFFECT.StatusComma", true); |       await this.setEffect(STATUSES.StatusComma, true); | ||||||
|     } |     } | ||||||
|     return result; |     return result; | ||||||
|   } |   } | ||||||
| @@ -2453,7 +2432,7 @@ export class RdDActor extends Actor { | |||||||
|         RdDItemSort.incrementBonusCase(this, selectedSort, rollData.tmr.coord); |         RdDItemSort.incrementBonusCase(this, selectedSort, rollData.tmr.coord); | ||||||
|  |  | ||||||
|         if (rollData.isSortReserve) { |         if (rollData.isSortReserve) { | ||||||
|           await this.sortMisEnReserve(rollData, selectedSort); |           await this.sortMisEnReserve(selectedSort, rollData.competence, rollData.tmr.coord, Number(selectedSort.system.ptreve_reel)); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
| @@ -2465,6 +2444,7 @@ export class RdDActor extends Actor { | |||||||
|       if (rolled.isETotal) { // Echec total ! |       if (rolled.isETotal) { // Echec total ! | ||||||
|         rollData.depenseReve = Math.min(reveActuel, Math.floor(rollData.depenseReve * 1.5)) |         rollData.depenseReve = Math.min(reveActuel, Math.floor(rollData.depenseReve * 1.5)) | ||||||
|         // TODO: mise en réserve d'un échec total... |         // TODO: mise en réserve d'un échec total... | ||||||
|  |         // await dialog mse en réserve, pour traitement échec total | ||||||
|       } else { |       } else { | ||||||
|         rollData.depenseReve = 0 |         rollData.depenseReve = 0 | ||||||
|       } |       } | ||||||
| @@ -3176,8 +3156,7 @@ export class RdDActor extends Actor { | |||||||
|       ui.notifications.warn("Vous êtes déja dans les TMR...."); |       ui.notifications.warn("Vous êtes déja dans les TMR...."); | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     let demiReve = this.getActiveEffects(it => it.label == "Demi-rêve"); |     if (mode != 'visu' &&  this.getEffect(STATUSES.StatusDemiReve)) { | ||||||
|     if (mode != 'visu' && demiReve.length > 0) { |  | ||||||
|       ui.notifications.warn("Le joueur ou le MJ est déja dans les Terres Médianes avec ce personnage ! Visualisation uniquement"); |       ui.notifications.warn("Le joueur ou le MJ est déja dans les Terres Médianes avec ce personnage ! Visualisation uniquement"); | ||||||
|       mode = "visu"; // bascule le mode en visu automatiquement |       mode = "visu"; // bascule le mode en visu automatiquement | ||||||
|     } |     } | ||||||
| @@ -3192,7 +3171,7 @@ export class RdDActor extends Actor { | |||||||
|         }); |         }); | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|       await this.setStatusEffect("EFFECT.StatusDemiReve", true); |       await this.setEffect(STATUSES.StatusDemiReve, true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const fatigue = this.system.sante.fatigue.value; |     const fatigue = this.system.sante.fatigue.value; | ||||||
| @@ -3482,7 +3461,7 @@ export class RdDActor extends Actor { | |||||||
|         count--; |         count--; | ||||||
|       } else { |       } else { | ||||||
|         // TODO: status effect dead |         // TODO: status effect dead | ||||||
|         this.setStatusEffect("EFFECT.StatusComma", true); |         this.setEffect(STATUSES.StatusComma, true); | ||||||
|         ChatMessage.create({ |         ChatMessage.create({ | ||||||
|           content: `<img class="chat-icon" src="icons/svg/skull.svg" alt="charge" /> |           content: `<img class="chat-icon" src="icons/svg/skull.svg" alt="charge" /> | ||||||
|           <strong>${this.name} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !</strong>` |           <strong>${this.name} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !</strong>` | ||||||
| @@ -4117,61 +4096,44 @@ export class RdDActor extends Actor { | |||||||
|   async onUpdateActor(update, options, actorId) { |   async onUpdateActor(update, options, actorId) { | ||||||
|     const updatedEndurance = update?.system?.sante?.endurance |     const updatedEndurance = update?.system?.sante?.endurance | ||||||
|     if (updatedEndurance && options.diff) { |     if (updatedEndurance && options.diff) { | ||||||
|       await this.setStatusEffect("EFFECT.StatusUnconscious", updatedEndurance.value == 0) |       await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onDeleteActiveEffect(effect, options) { |   getEffects() { | ||||||
|     switch (effect.label) { |     return this.getEmbeddedCollection("ActiveEffect"); | ||||||
|       case 'EFFECT.StatusStunned': |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   getActiveEffects(matching = it => true) { |   getEffect(statusId) { | ||||||
|     return Array.from(this.getEmbeddedCollection("ActiveEffect").values()).filter(it => matching(it)); |     return this.getEmbeddedCollection("ActiveEffect").find(it => it.flags?.core?.statusId == statusId); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   getEffectByLabel(label) { |   async setEffect(statusId, status) { | ||||||
|     return this.getActiveEffects().find(it => it.system?.label == label); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   getEffectById(id) { |  | ||||||
|     return this.getActiveEffects().find(it => it.id == id); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async setStatusEffect(label, status, updates = {}) { |  | ||||||
|     if (this.isEntite() || this.type == 'vehicule') { |     if (this.isEntite() || this.type == 'vehicule') { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     console.log("setStatusEffect", label, status, updates) |     console.log("setEffect", statusId, status) | ||||||
|     const existing = this.getEffectByLabel(label); |     await this.removeEffect(statusId); | ||||||
|     if (existing) { |     const effect = StatusEffects.status(statusId); | ||||||
|       existing.delete(); |     if (effect) { | ||||||
|     } |       await this.createEmbeddedDocuments("ActiveEffect", [effect]); | ||||||
|     if (status) { |  | ||||||
|       const statusEffect = mergeObject(duplicate(StatusEffects.status(label)), updates); |  | ||||||
|       await this.createEmbeddedDocuments("ActiveEffect", [statusEffect]); |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   enleverActiveEffectById(id) { |   async removeEffect(statusId) { | ||||||
|     if (game.user.isGM) { |     const effect = this.getEffect(statusId); | ||||||
|       const existing = this.getEffectById(id); |     if (effect) { | ||||||
|       if (existing) { |       await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]); | ||||||
|         existing.delete(); |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   enleverTousLesEffets() { |   enleverTousLesEffets() { | ||||||
|     if (game.user.isGM) { |     if (game.user.isGM) { | ||||||
|       this.deleteEmbeddedDocuments('ActiveEffect', this.getActiveEffects().map(it => it.id)); |       this.deleteEmbeddedDocuments('ActiveEffect', this.getEffects().map(it => it.id)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon'; | export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon'; | ||||||
| export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon'; | export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon'; | ||||||
|  | export const LOG_HEAD = 'RdD | '; | ||||||
|  |  | ||||||
| export const HIDE_DICE = 'hide'; | export const HIDE_DICE = 'hide'; | ||||||
| export const SHOW_DICE = 'show'; | export const SHOW_DICE = 'show'; | ||||||
|   | |||||||
| @@ -84,32 +84,36 @@ export class RdDItemSheet extends ItemSheet { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences() |     formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences() | ||||||
|     if (formData.type == 'tache' || formData.type == 'livre' || formData.type == 'meditation' || formData.type == 'oeuvre') { |     if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') { | ||||||
|       formData.caracList = duplicate(game.system.model.Actor.personnage.carac) |       formData.caracList = duplicate(game.system.model.Actor.personnage.carac) | ||||||
|       formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve) |       formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve) | ||||||
|       formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences') |       formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences') | ||||||
|     } |     } | ||||||
|     if (formData.type == 'arme') { |     if (this.item.type == 'arme') { | ||||||
|       formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it)); |       formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it)); | ||||||
|       console.log(formData.competences) |       console.log(formData.competences) | ||||||
|     } |     } | ||||||
|     if (formData.type == 'recettealchimique') { |     if (this.item.type == 'recettealchimique') { | ||||||
|       RdDAlchimie.processManipulation(this.item, this.actor && this.actor.id); |       RdDAlchimie.processManipulation(this.item, this.actor && this.actor.id); | ||||||
|     } |     } | ||||||
|     if (formData.type == 'gemme') { |     if (this.item.type == 'gemme') { | ||||||
|       formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList(); |       formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList(); | ||||||
|       RdDGemme.calculDataDerivees(this.item); |       RdDGemme.calculDataDerivees(this.item); | ||||||
|     } |     } | ||||||
|     if (formData.type == 'potion') { |     if (this.item.type == 'potion') { | ||||||
|       if (this.dateUpdated) { |       if (this.dateUpdated) { | ||||||
|         formData.system.prdate = this.dateUpdated; |         formData.system.prdate = this.dateUpdated; | ||||||
|         this.dateUpdated = undefined; |         this.dateUpdated = undefined; | ||||||
|       } |       } | ||||||
|       RdDHerbes.updatePotionData(formData); |       RdDHerbes.updatePotionData(formData); | ||||||
|     } |     } | ||||||
|     if (formData.isOwned && formData.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) { |     if (formData.isOwned && this.item.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) { | ||||||
|       formData.isIngredientPotionBase = true; |       formData.isIngredientPotionBase = true; | ||||||
|     } |     } | ||||||
|  |     if (this.item.type == 'sortreserve') { | ||||||
|  |       const sortId = this.item.system.sortid; | ||||||
|  |       formData.sort = formData.isOwned ? this.item.actor.items.get(sortId) : game.items.get(sortId); | ||||||
|  |     } | ||||||
|     formData.bonusCaseList = RdDItemSort.getBonusCaseList(formData, true); |     formData.bonusCaseList = RdDItemSort.getBonusCaseList(formData, true); | ||||||
|  |  | ||||||
|     return formData; |     return formData; | ||||||
|   | |||||||
| @@ -36,7 +36,8 @@ export const defaultItemImg = { | |||||||
|   nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp", |   nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp", | ||||||
|   signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp", |   signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp", | ||||||
|   gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp", |   gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp", | ||||||
|   possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp" |   possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", | ||||||
|  |   sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", | ||||||
| } | } | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
|   | |||||||
							
								
								
									
										103
									
								
								module/migrations.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								module/migrations.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | import { LOG_HEAD, SYSTEM_RDD } from "./constants.js"; | ||||||
|  |  | ||||||
|  | class Migration { | ||||||
|  |   get code() { return "sample"; } | ||||||
|  |   get version() { return "0.0.0"; } | ||||||
|  |   async migrate() { } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _10_0_16_MigrationSortsReserve extends Migration { | ||||||
|  |   get code() { return "creation-item-sort-reserve"; } | ||||||
|  |   get version() { return "10.0.16"; } | ||||||
|  |  | ||||||
|  |   async migrate() { | ||||||
|  |     await game.actors | ||||||
|  |       .filter((actor) => actor.type == "personnage") | ||||||
|  |       .filter((actor) => actor.system.reve?.reserve?.list?.length ?? 0 > 0) | ||||||
|  |       .forEach(async (actor) => { | ||||||
|  |         const sortsReserve = actor.system.reve.reserve.list.map(this.conversionSortReserve); | ||||||
|  |         console.log(LOG_HEAD + "Migration des sorts ", sortsReserve); | ||||||
|  |         await actor.createEmbeddedDocuments("Item", sortsReserve, { | ||||||
|  |           renderSheet: false, | ||||||
|  |         }); | ||||||
|  |         await actor.update({'system.reve.reserve.list':[]}) | ||||||
|  |       }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   conversionSortReserve(it) { | ||||||
|  |     return { | ||||||
|  |       type: 'sortreserve', | ||||||
|  |       name: it.sort.name, | ||||||
|  |       img: it.sort.img, | ||||||
|  |       system: { | ||||||
|  |         // ATTENTION, utilisation de data / _id possibles, encore présents pour les anciens sorts en réserve | ||||||
|  |         sortid: it.sort._id, | ||||||
|  |         draconic: it.sort.draconic, | ||||||
|  |         ptreve: (it.sort.system ?? it.sort.data).ptreve_reel, | ||||||
|  |         coord: it.coord, | ||||||
|  |         heurecible: 'Vaisseau', | ||||||
|  |       }, | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export class Migrations { | ||||||
|  |   static getMigrations() { | ||||||
|  |     return [ | ||||||
|  |       new _10_0_16_MigrationSortsReserve() | ||||||
|  |     ]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   constructor() { | ||||||
|  |     game.settings.register(SYSTEM_RDD, "systemMigrationVersion", { | ||||||
|  |       name: "System Migration Version", | ||||||
|  |       scope: "world", | ||||||
|  |       config: false, | ||||||
|  |       type: String, | ||||||
|  |       default: "0.0.0", | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   migrate() { | ||||||
|  |     const currentVersion = game.settings.get( | ||||||
|  |       SYSTEM_RDD, | ||||||
|  |       "systemMigrationVersion" | ||||||
|  |     ); | ||||||
|  |     if (isNewerVersion(game.system.version, currentVersion)) { | ||||||
|  |       const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion)); | ||||||
|  |     // if (true) { | ||||||
|  |     //   const migrations = Migrations.getMigrations(); | ||||||
|  |       if (migrations.length > 0) { | ||||||
|  |         migrations.sort((a, b) => | ||||||
|  |           isNewerVersion(a.version, b.version) | ||||||
|  |             ? 1 | ||||||
|  |             : isNewerVersion(b.version, a.version) | ||||||
|  |             ? -1 | ||||||
|  |             : 0 | ||||||
|  |         ); | ||||||
|  |         migrations.forEach(async (m) => { | ||||||
|  |           ui.notifications.info( | ||||||
|  |             `Executing migration ${m.code}: version ${currentVersion} is lower than ${m.version}` | ||||||
|  |           ); | ||||||
|  |           await m.migrate(); | ||||||
|  |         }); | ||||||
|  |         ui.notifications.info( | ||||||
|  |           `Migrations done, version will change to ${game.system.version}` | ||||||
|  |         ); | ||||||
|  |       } else { | ||||||
|  |         console.log( | ||||||
|  |           LOG_HEAD + | ||||||
|  |             `No migration needeed, version will change to ${game.system.version}` | ||||||
|  |         ); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       game.settings.set( | ||||||
|  |         SYSTEM_RDD, | ||||||
|  |         "systemMigrationVersion", | ||||||
|  |         game.system.version | ||||||
|  |       ); | ||||||
|  |     } else { | ||||||
|  |       console.log(LOG_HEAD + `No system version changed`); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -10,6 +10,7 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js"; | |||||||
| import { RdDRoll } from "./rdd-roll.js"; | import { RdDRoll } from "./rdd-roll.js"; | ||||||
| import { RdDRollTables } from "./rdd-rolltables.js"; | import { RdDRollTables } from "./rdd-rolltables.js"; | ||||||
| import { ReglesOptionelles } from "./regles-optionelles.js"; | import { ReglesOptionelles } from "./regles-optionelles.js"; | ||||||
|  | import { STATUSES } from "./status-effects.js"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| const premierRoundInit = [ | const premierRoundInit = [ | ||||||
| @@ -1185,7 +1186,7 @@ export class RdDCombat { | |||||||
|         defenderRoll.show.recul = 'encaisse'; |         defenderRoll.show.recul = 'encaisse'; | ||||||
|       } else if (rollRecul.rolled.isETotal || this._isReculCauseChute(impact)) { |       } else if (rollRecul.rolled.isETotal || this._isReculCauseChute(impact)) { | ||||||
|         defenderRoll.show.recul = 'chute'; |         defenderRoll.show.recul = 'chute'; | ||||||
|         await this.defender.setStatusEffect("EFFECT.StatusProne", true); |         await this.defender.setEffect(STATUSES.StatusProne, true); | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|         defenderRoll.show.recul = 'recul'; |         defenderRoll.show.recul = 'recul'; | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ import { RdDDice } from "./rdd-dice.js"; | |||||||
| import { RdDPossession } from "./rdd-possession.js"; | import { RdDPossession } from "./rdd-possession.js"; | ||||||
| import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js"; | import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
|  | import { Migrations } from './migrations.js'; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| /*  Foundry VTT Initialization                  */ | /*  Foundry VTT Initialization                  */ | ||||||
| @@ -183,7 +184,7 @@ Hooks.once("init", async function () { | |||||||
|   Items.registerSheet(SYSTEM_RDD, RdDItemSheet, { |   Items.registerSheet(SYSTEM_RDD, RdDItemSheet, { | ||||||
|     types: ["arme", "armure", "objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle", |     types: ["arme", "armure", "objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle", | ||||||
|       "tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique", "gemme", |       "tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique", "gemme", | ||||||
|       "musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "possession"], makeDefault: true |       "musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "possession", "sortreserve"], makeDefault: true | ||||||
|   }); |   }); | ||||||
|   CONFIG.Combat.documentClass = RdDCombatManager; |   CONFIG.Combat.documentClass = RdDCombatManager; | ||||||
|  |  | ||||||
| @@ -245,6 +246,9 @@ function registerUsageCount( registerKey ) { | |||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| Hooks.once("ready", async function () { | Hooks.once("ready", async function () { | ||||||
|   await migrationPngWebp_1_5_34() |   await migrationPngWebp_1_5_34() | ||||||
|  |   if (Misc.isUniqueConnectedGM()) { | ||||||
|  |     new Migrations().migrate(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   StatusEffects.onReady(); |   StatusEffects.onReady(); | ||||||
|   RdDHerbes.initializeHerbes(); |   RdDHerbes.initializeHerbes(); | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| import { SYSTEM_SOCKET_ID } from "./constants.js"; |  | ||||||
| import { RollDataAjustements } from "./rolldata-ajustements.js"; | import { RollDataAjustements } from "./rolldata-ajustements.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
| import { TMRUtility } from "./tmr-utility.js"; | import { TMRUtility } from "./tmr-utility.js"; | ||||||
| @@ -16,6 +15,7 @@ import { Misc } from "./misc.js"; | |||||||
| import { HtmlUtility } from "./html-utility.js"; | import { HtmlUtility } from "./html-utility.js"; | ||||||
| import { ReglesOptionelles } from "./regles-optionelles.js"; | import { ReglesOptionelles } from "./regles-optionelles.js"; | ||||||
| import { RdDDice } from "./rdd-dice.js"; | import { RdDDice } from "./rdd-dice.js"; | ||||||
|  | import { STATUSES } from "./status-effects.js"; | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
|  |  | ||||||
| export class RdDTMRDialog extends Dialog { | export class RdDTMRDialog extends Dialog { | ||||||
| @@ -55,7 +55,6 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     this.fatigueParCase = this.viewOnly || !ReglesOptionelles.isUsing("appliquer-fatigue") ? 0 : this.actor.getTMRFatigue(); |     this.fatigueParCase = this.viewOnly || !ReglesOptionelles.isUsing("appliquer-fatigue") ? 0 : this.actor.getTMRFatigue(); | ||||||
|     this.cumulFatigue = 0; |     this.cumulFatigue = 0; | ||||||
|     this.loadRencontres(); |     this.loadRencontres(); | ||||||
|     this.loadSortsReserve(); |  | ||||||
|     this.loadCasesSpeciales(); |     this.loadCasesSpeciales(); | ||||||
|     this.allTokens = []; |     this.allTokens = []; | ||||||
|     this.rencontreState = 'aucune'; |     this.rencontreState = 'aucune'; | ||||||
| @@ -81,9 +80,16 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     this.casesSpeciales = this.actor.items.filter(item => Draconique.isCaseTMR(item)); |     this.casesSpeciales = this.actor.items.filter(item => Draconique.isCaseTMR(item)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   get sortsReserve() { | ||||||
|   loadSortsReserve() { |     return this.actor.itemTypes['sortreserve']; | ||||||
|     this.sortsReserves = this.actor.system.reve.reserve.list; |   } | ||||||
|  |  | ||||||
|  |   getSortsReserve(coord) { | ||||||
|  |     return this.actor.itemTypes['sortreserve'].filter(// Reserve sur une case fleuve ou normale | ||||||
|  |       TMRUtility.getTMR(coord).type == 'fleuve' | ||||||
|  |         ? it => TMRUtility.getTMR(it.system.coord).type == 'fleuve' | ||||||
|  |         : it => it.system.coord == coord | ||||||
|  |       ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -97,10 +103,10 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     this.updateTokens(); |     this.updateTokens(); | ||||||
|     this.forceDemiRevePositionView(); |     this.forceDemiRevePositionView(); | ||||||
|   } |   } | ||||||
|    |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _createTokens() { |   _createTokens() { | ||||||
|     if (!this.isDemiReveCache()){ |     if (!this.isDemiReveCache()) { | ||||||
|       this.demiReve = this._tokenDemiReve(); |       this.demiReve = this._tokenDemiReve(); | ||||||
|       this._trackToken(this.demiReve); |       this._trackToken(this.demiReve); | ||||||
|     } |     } | ||||||
| @@ -117,7 +123,6 @@ export class RdDTMRDialog extends Dialog { | |||||||
|   updateTokens() { |   updateTokens() { | ||||||
|     this._removeTokens(t => true); |     this._removeTokens(t => true); | ||||||
|     this.loadRencontres(); |     this.loadRencontres(); | ||||||
|     this.loadSortsReserve(); |  | ||||||
|     this.loadCasesSpeciales(); |     this.loadCasesSpeciales(); | ||||||
|     this._createTokens(); |     this._createTokens(); | ||||||
|   } |   } | ||||||
| @@ -136,7 +141,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     return this.rencontresExistantes.map(it => this._tokenRencontre(it)); |     return this.rencontresExistantes.map(it => this._tokenRencontre(it)); | ||||||
|   } |   } | ||||||
|   _getTokensSortsReserve() { |   _getTokensSortsReserve() { | ||||||
|     return this.sortsReserves.map(it => this._tokenSortEnReserve(it)); |     return this.actor.itemTypes['sortreserve'].map(it => this._tokenSortEnReserve(it)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -148,8 +153,8 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     const draconique = Draconique.get(caseData.system.specific); |     const draconique = Draconique.get(caseData.system.specific); | ||||||
|     return draconique?.token(this.pixiTMR, caseData, () => caseData.system.coord); |     return draconique?.token(this.pixiTMR, caseData, () => caseData.system.coord); | ||||||
|   } |   } | ||||||
|   _tokenSortEnReserve(sortEnReserve) { |   _tokenSortEnReserve(sortReserve) { | ||||||
|     return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortEnReserve.sort, () => sortEnReserve.coord); |     return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortReserve, () => sortReserve.system.coord); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   _tokenDemiReve() { |   _tokenDemiReve() { | ||||||
| @@ -254,9 +259,9 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|     let tmrpos = document.getElementById("tmr-pos"); |     let tmrpos = document.getElementById("tmr-pos"); | ||||||
|     if (this.isDemiReveCache()) { |     if (this.isDemiReveCache()) { | ||||||
|       tmrpos.innerHTML = '?? (' + TMRUtility.getTMRType(coord) + ')'; |       tmrpos.innerHTML = `?? ( ${ TMRUtility.getTMRType(coord)})`; | ||||||
|     } else { |     } else { | ||||||
|       tmrpos.innerHTML = coord + " (" + TMRUtility.getTMRLabel(coord) + ")"; |       tmrpos.innerHTML = `${coord} ( ${TMRUtility.getTMRLabel(coord)})`; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     let etat = document.getElementById("tmr-etatgeneral-value"); |     let etat = document.getElementById("tmr-etatgeneral-value"); | ||||||
| @@ -272,15 +277,16 @@ export class RdDTMRDialog extends Dialog { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   close() { |   async close() { | ||||||
|     if ( this.actor.tmrApp ) {  |     if (this.actor.tmrApp) { | ||||||
|       this.actor.tmrApp = undefined; // Cleanup reference |       this.actor.tmrApp = undefined; // Cleanup reference | ||||||
|       if ( !this.viewOnly ) { |       if (!this.viewOnly) { | ||||||
|         this.actor.setStatusEffect("EFFECT.StatusDemiReve", false); |         await this.actor.setEffect(STATUSES.StatusDemiReve, false) | ||||||
|         this._tellToGM(this.actor.name + " a quitté les terres médianes"); |         this._tellToGM(this.actor.name + " a quitté les terres médianes"); | ||||||
|       } |       } | ||||||
|       this.actor.santeIncDec("fatigue", this.cumulFatigue).then(super.close()); // moving 1 cell costs 1 fatigue |       await this.actor.santeIncDec("fatigue", this.cumulFatigue) | ||||||
|     } |     } | ||||||
|  |     await super.close(); // moving 1 cell costs 1 fatigue | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -316,11 +322,11 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     this.currentRencontre.graphics = []; // Keep track of rectangles to delete it |     this.currentRencontre.graphics = []; // Keep track of rectangles to delete it | ||||||
|     this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location |     this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location | ||||||
|     for (let coordTMR of listCoordTMR) { |     for (let coordTMR of listCoordTMR) { | ||||||
|       let rect = this._getCaseRectangleCoord(coordTMR); |       const rect = this._getCaseRectangleCoord(coordTMR); | ||||||
|       var rectDraw = new PIXI.Graphics(); |       const rectDraw = new PIXI.Graphics(); | ||||||
|       rectDraw.beginFill(0xFFFF00, 0.3); |       rectDraw.beginFill(0xffff00, 0.3); | ||||||
|       // set the line style to have a width of 5 and set the color to red |       // set the line style to have a width of 5 and set the color to red | ||||||
|       rectDraw.lineStyle(5, 0xFF0000); |       rectDraw.lineStyle(5, 0xff0000); | ||||||
|       // draw a rectangle |       // draw a rectangle | ||||||
|       rectDraw.drawRect(rect.x, rect.y, rect.w, rect.h); |       rectDraw.drawRect(rect.x, rect.y, rect.w, rect.h); | ||||||
|       this.pixiApp.stage.addChild(rectDraw); |       this.pixiApp.stage.addChild(rectDraw); | ||||||
| @@ -336,19 +342,13 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async choisirCasePortee(coord, portee) { |   async choisirCasePortee(coord, portee) { | ||||||
|     if (this.actor.isTMRCache()) |  | ||||||
|     { |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     // Récupère la liste des cases à portées |     // Récupère la liste des cases à portées | ||||||
|     let locList = TMRUtility.getTMRPortee(coord, portee); |     this.colorierZoneRencontre(TMRUtility.getTMRPortee(coord, portee)); | ||||||
|     this.colorierZoneRencontre(locList); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async choisirCaseType(type) { |   async choisirCaseType(type) { | ||||||
|     const locList = TMRUtility.filterTMR(it => it.type == type).map(it => it.coord); |     this.colorierZoneRencontre(TMRUtility.filterTMR(it => it.type == type).map(it => it.coord)); | ||||||
|     this.colorierZoneRencontre(locList); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -573,6 +573,9 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async manageTmrInnaccessible(tmr) { |   async manageTmrInnaccessible(tmr) { | ||||||
|  |     if (!tmr) { | ||||||
|  |       return await this.actor.reinsertionAleatoire('Sortie de carte'); | ||||||
|  |     } | ||||||
|     const caseTmrInnaccessible = this.casesSpeciales.find(c => EffetsDraconiques.isInnaccessible(c, tmr.coord)); |     const caseTmrInnaccessible = this.casesSpeciales.find(c => EffetsDraconiques.isInnaccessible(c, tmr.coord)); | ||||||
|     if (caseTmrInnaccessible) { |     if (caseTmrInnaccessible) { | ||||||
|       return await this.actor.reinsertionAleatoire(caseTmrInnaccessible.name); |       return await this.actor.reinsertionAleatoire(caseTmrInnaccessible.name); | ||||||
| @@ -774,9 +777,8 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async declencheSortEnReserve(coord) { |   async declencheSortEnReserve(coord) { | ||||||
|  |     let sorts = this.getSortsReserve(coord); | ||||||
|     let sortsEnCoord = TMRUtility.getSortsReserve(this.sortsReserves, coord); |     if (sorts.length > 0) { | ||||||
|     if (sortsEnCoord.length > 0) { |  | ||||||
|       if (EffetsDraconiques.isSortReserveImpossible(this.actor)) { |       if (EffetsDraconiques.isSortReserveImpossible(this.actor)) { | ||||||
|         ui.notifications.error("Une queue ou un souffle vous empèche de déclencher de sort!"); |         ui.notifications.error("Une queue ou un souffle vous empèche de déclencher de sort!"); | ||||||
|         return; |         return; | ||||||
| @@ -784,8 +786,8 @@ export class RdDTMRDialog extends Dialog { | |||||||
|       if (!EffetsDraconiques.isUrgenceDraconique(this.actor) && |       if (!EffetsDraconiques.isUrgenceDraconique(this.actor) && | ||||||
|         (EffetsDraconiques.isReserveEnSecurite(this.actor) || this.isReserveExtensible(coord))) { |         (EffetsDraconiques.isReserveEnSecurite(this.actor) || this.isReserveExtensible(coord))) { | ||||||
|         let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête <strong>Reserve en Sécurité</strong> ou <strong>Réserve Exensible</strong>, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher : <ul>"; |         let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête <strong>Reserve en Sécurité</strong> ou <strong>Réserve Exensible</strong>, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher : <ul>"; | ||||||
|         for (let sortReserve of sortsEnCoord) { |         for (let sort of sorts) { | ||||||
|           msg += "<li><a class='chat-card-button' id='sort-reserve' data-actor-id='" + this.actor._id + "' data-tmr-coord='" + coord + "' data-sort-id='" + sortReserve.sort._id + "'>" + sortReserve.sort.name + "</a></li>"; |           msg += `<li><a class="chat-card-button declencher-sort-reserve" data-actor-id="${this.actor.id}" data-tmr-coord="${coord}" data-sort-id='${sort.id}">${sort.name}</a></li>`; | ||||||
|         } |         } | ||||||
|         msg += "</ol>"; |         msg += "</ol>"; | ||||||
|         ChatMessage.create({ |         ChatMessage.create({ | ||||||
| @@ -794,33 +796,35 @@ export class RdDTMRDialog extends Dialog { | |||||||
|         }); |         }); | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|       await this.processSortReserve(sortsEnCoord[0]); |       await this.processSortReserve(sorts[0]); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   lancerSortEnReserve(coord, sortId) { |   lancerSortEnReserve(coord, sortId) { | ||||||
|     let sortEnCoord = TMRUtility.getSortsReserve(this.sortsReserves, coord); |     let sorts = this.getSortsReserve(coord); | ||||||
|     let sortReserve = sortEnCoord.find(sortReserve => sortReserve.sort._id == sortId); |     let sort = sorts.find(it => it.id == sortId); | ||||||
|     if (sortReserve) { |     if (sort) { | ||||||
|       this.processSortReserve(sortReserve); |       this.processSortReserve(sort); | ||||||
|     } else { |     } else { | ||||||
|       ChatMessage.create({ |       ChatMessage.create({ | ||||||
|         content: "Une erreur est survenue : impossible de récupérer le sort en réserve demandé.", |         content: | ||||||
|         whisper: ChatMessage.getWhisperRecipients(game.user.name) |           "Une erreur est survenue : impossible de récupérer le sort en réserve demandé.", | ||||||
|  |         whisper: ChatMessage.getWhisperRecipients(game.user.name), | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async processSortReserve(sortReserve) { |   async processSortReserve(sortReserve) { | ||||||
|     await this.actor.deleteSortReserve(sortReserve); |     await this.actor.deleteEmbeddedDocuments('Item', [sortReserve.id]); | ||||||
|     //this.updateSortReserve(); |     console.log("declencheSortEnReserve", sortReserve); | ||||||
|     console.log("declencheSortEnReserve", sortReserve) |     this._tellToUserAndGM(`Vous avez déclenché  | ||||||
|     this._tellToUserAndGM(`Vous avez déclenché le sort en réserve <strong> ${sortReserve.sort.name}</strong> |         ${sortReserve.system.echectotal ? "<strong>l'échec total!</strong>" : "le sort"} | ||||||
|         avec ${sortReserve.sort.data.ptreve_reel} points de Rêve |         en réserve <strong>${sortReserve.name}</strong> | ||||||
|         en ${sortReserve.coord} (${TMRUtility.getTMRLabel(sortReserve.coord)}) |         avec ${sortReserve.system.ptreve} points de Rêve | ||||||
|         `); |         en ${sortReserve.system.coord} (${TMRUtility.getTMRLabel(sortReserve.system.coord)}). | ||||||
|  |         L'heure ciblée est ${sortReserve.system.heurecible}`); | ||||||
|     this.close(); |     this.close(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -926,7 +930,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|     const isInArea = this.rencontreState == 'aucune' |     const isInArea = this.rencontreState == 'aucune' | ||||||
|       ? (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1) |       ? (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1) | ||||||
|       : this.currentRencontre?.locList.find(coord => coord == targetCoord) ?? false |       : this.currentRencontre?.locList?.find(coord => coord == targetCoord) ?? false | ||||||
|     if (isInArea) { |     if (isInArea) { | ||||||
|       switch (this.rencontreState) { |       switch (this.rencontreState) { | ||||||
|         case 'aucune': return 'normal'; |         case 'aucune': return 'normal'; | ||||||
| @@ -994,6 +998,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async postRencontre(tmr) { |   async postRencontre(tmr) { | ||||||
|     if (!(this.viewOnly || this.currentRencontre)) { |     if (!(this.viewOnly || this.currentRencontre)) { | ||||||
|  |       // TODO: vérifier que la méthode s'arrête en cas de non-maîtrise | ||||||
|       await this.manageCaseHumide(tmr); |       await this.manageCaseHumide(tmr); | ||||||
|       await this.conquerirCiteFermee(tmr); |       await this.conquerirCiteFermee(tmr); | ||||||
|       await this.purifierPeriple(tmr); |       await this.purifierPeriple(tmr); | ||||||
| @@ -1019,7 +1024,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     let x = origEvent.clientX - canvasRect.left; |     let x = origEvent.clientX - canvasRect.left; | ||||||
|     let y = origEvent.clientY - canvasRect.top; |     let y = origEvent.clientY - canvasRect.top; | ||||||
|     let col = Math.floor(x / tmrConstants.cellw); //  [From 0 -> 12] |     let col = Math.floor(x / tmrConstants.cellw); //  [From 0 -> 12] | ||||||
|     y -= (col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y; |     y -= col % 2 == 0 ? tmrConstants.col1_y : tmrConstants.col2_y; | ||||||
|     let row = Math.floor(y / tmrConstants.cellh); //  [From 0 -> 14] |     let row = Math.floor(y / tmrConstants.cellh); //  [From 0 -> 14] | ||||||
|     return { col: col, row: row }; |     return { col: col, row: row }; | ||||||
|   } |   } | ||||||
| @@ -1029,7 +1034,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|   _getCaseRectangleCoord(coord) { |   _getCaseRectangleCoord(coord) { | ||||||
|     return this.pixiTMR.getCaseRectangle(TMRUtility.coordTMRToOddq(coord)); |     return this.pixiTMR.getCaseRectangle(TMRUtility.coordTMRToOddq(coord)); | ||||||
|   } |   } | ||||||
|    |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _removeTokens(filter) { |   _removeTokens(filter) { | ||||||
|     const tokensToRemove = this.allTokens.filter(filter); |     const tokensToRemove = this.allTokens.filter(filter); | ||||||
| @@ -1037,7 +1042,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|       this.pixiApp.stage.removeChild(token.sprite); |       this.pixiApp.stage.removeChild(token.sprite); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|    |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _trackToken(token) { |   _trackToken(token) { | ||||||
|     if (this.demiReve === token && this.isDemiReveCache()) { |     if (this.demiReve === token && this.isDemiReveCache()) { | ||||||
|   | |||||||
| @@ -393,6 +393,7 @@ export class RdDUtility { | |||||||
|     formData.possessions = this.arrayOrEmpty(formData.itemsByType['possession']); |     formData.possessions = this.arrayOrEmpty(formData.itemsByType['possession']); | ||||||
|     formData.maladiesPoisons = formData.maladies.concat(formData.poisons); |     formData.maladiesPoisons = formData.maladies.concat(formData.poisons); | ||||||
|     formData.competences = (formData.itemsByType.competence ?? []).concat(formData.itemsByType.competencecreature ?? []); |     formData.competences = (formData.itemsByType.competence ?? []).concat(formData.itemsByType.competencecreature ?? []); | ||||||
|  |     formData.sortsReserve = this.arrayOrEmpty(formData.itemsByType['sortreserve']); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static filterEquipementParType(formData) { |   static filterEquipementParType(formData) { | ||||||
| @@ -693,12 +694,13 @@ export class RdDUtility { | |||||||
|       actor.tmrApp.positionnerDemiReve(coord); |       actor.tmrApp.positionnerDemiReve(coord); | ||||||
|     }); |     }); | ||||||
|     // Gestion spécifique des sorts en réserve multiples (ie têtes) |     // Gestion spécifique des sorts en réserve multiples (ie têtes) | ||||||
|     html.on("click", '#sort-reserve', event => { |     html.on("click", '.declencher-sort-reserve', event => { | ||||||
|       let coord = event.currentTarget.attributes['data-tmr-coord'].value; |       let coord = event.currentTarget.attributes['data-tmr-coord'].value; | ||||||
|       let sortId = event.currentTarget.attributes['data-sort-id'].value; |       let sortId = event.currentTarget.attributes['data-sort-id'].value; | ||||||
|       let actorId = event.currentTarget.attributes['data-actor-id'].value; |       let actorId = event.currentTarget.attributes['data-actor-id'].value; | ||||||
|       let actor = game.actors.get(actorId); |       let actor = game.actors.get(actorId); | ||||||
|       actor.tmrApp.lancerSortEnReserve(coord, sortId); |       actor.tmrApp.lancerSortEnReserve(coord, sortId); | ||||||
|  |       // TODO: supprimer le message? | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     // gestion bouton tchat Possession |     // gestion bouton tchat Possession | ||||||
| @@ -881,7 +883,7 @@ export class RdDUtility { | |||||||
|         label: "Supprimer l'objet", |         label: "Supprimer l'objet", | ||||||
|         callback: () => { |         callback: () => { | ||||||
|           console.log("Delete : ", itemId); |           console.log("Delete : ", itemId); | ||||||
|           sheet.actor.deleteEmbeddedDocuments('Item', [itemId]); |           sheet.actor.deleteEmbeddedDocuments('Item', [itemId], { renderSheet: false }); | ||||||
|           RdDUtility.slideOnDelete(sheet, htmlToDelete); |           RdDUtility.slideOnDelete(sheet, htmlToDelete); | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
| @@ -897,7 +899,7 @@ export class RdDUtility { | |||||||
|         label: "Supprimer le conteneur et tout son contenu", |         label: "Supprimer le conteneur et tout son contenu", | ||||||
|         callback: () => { |         callback: () => { | ||||||
|           console.log("Delete : ", itemId); |           console.log("Delete : ", itemId); | ||||||
|           sheet.actor.deleteAllConteneur(itemId); |           sheet.actor.deleteAllConteneur(itemId, { renderSheet: false }); | ||||||
|           RdDUtility.slideOnDelete(sheet, htmlToDelete); |           RdDUtility.slideOnDelete(sheet, htmlToDelete); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -1,26 +1,41 @@ | |||||||
| import { SYSTEM_RDD } from "./constants.js"; | import { SYSTEM_RDD } from "./constants.js"; | ||||||
|  |  | ||||||
| const rddStatusEffects = [ | export const STATUSES = { | ||||||
|   { rdd: true, id: 'stun', label: 'EFFECT.StatusStunned', icon: 'icons/svg/stoned.svg', "duration.rounds": 1 }, |   StatusStunned : 'stun', | ||||||
|   { rdd: true, id: 'bleeding', label: 'EFFECT.StatusBleeding', icon: 'icons/svg/blood.svg' }, |   StatusBleeding: 'bleeding', | ||||||
|   { rdd: true, id: 'prone', label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg' }, |   StatusProne: 'prone', | ||||||
|   { rdd: true, id: 'grappling', tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' }, |   StatusGrappling: 'grappling', | ||||||
|   { rdd: true, id: 'grappled', tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' }, |   StatusGrappled: 'grappled', | ||||||
|   { rdd: true, id: 'restrain', label: 'EFFECT.StatusRestrained', icon: 'icons/svg/net.svg' }, |   StatusRestrained: 'restrain', | ||||||
|   { rdd: true, id: 'unconscious', label: 'EFFECT.StatusUnconscious', icon: 'icons/svg/unconscious.svg' }, |   StatusUnconscious: 'unconscious',  | ||||||
|   { rdd: true, id: 'blind', label: 'EFFECT.StatusBlind', icon: 'icons/svg/blind.svg' }, |   StatusBlind: 'blind', | ||||||
|   { rdd: true, id: 'comma', label: 'EFFECT.StatusComma', icon: 'icons/svg/skull.svg' }, |   StatusComma: 'comma', | ||||||
|   { rdd: true, id: 'dead', label: 'EFFECT.StatusDead', icon: 'icons/svg/skull.svg' }, |   StatusDead: 'dead', | ||||||
|   { rdd: true, id: 'demi-reve', label: 'EFFECT.StatusDemiReve', icon: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' } |   StatusDemiReve: 'demi-reve', | ||||||
| ]; | } | ||||||
| const demiReveStatusEffect = rddStatusEffects.find(it => it.label == 'EFFECT.StatusDemiReve'); |  | ||||||
|  |  | ||||||
| const statusDemiSurprise = new Set(['EFFECT.StatusStunned', 'EFFECT.StatusProne', 'EFFECT.StatusRestrain']); | const rddStatusEffects = [ | ||||||
| const statusSurpriseTotale = new Set(['EFFECT.StatusUnconscious', 'EFFECT.StatusBlind', 'EFFECT.StatusComma']); |   { rdd: true, id: STATUSES.StatusStunned, label: 'EFFECT.StatusStunned', icon: 'icons/svg/stoned.svg', "duration.rounds": 1 }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusBleeding, label: 'EFFECT.StatusBleeding', icon: 'icons/svg/blood.svg' }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusProne, label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg' }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusRestrained, label: 'EFFECT.StatusRestrained', icon: 'icons/svg/net.svg' }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusUnconscious, label: 'EFFECT.StatusUnconscious', icon: 'icons/svg/unconscious.svg' }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusBlind, label: 'EFFECT.StatusBlind', icon: 'icons/svg/blind.svg' }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusComma, label: 'EFFECT.StatusComma', icon: 'icons/svg/skull.svg' }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusDead, label: 'EFFECT.StatusDead', icon: 'icons/svg/skull.svg' }, | ||||||
|  |   { rdd: true, id: STATUSES.StatusDemiReve, label: 'EFFECT.StatusDemiReve', icon: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' } | ||||||
|  | ]; | ||||||
|  | const demiReveStatusEffect = rddStatusEffects.find(it => it.id == STATUSES.StatusDemiReve); | ||||||
|  |  | ||||||
|  | const statusDemiSurprise = [STATUSES.StatusStunned, STATUSES.StatusProne, STATUSES.StatusRestrained]; | ||||||
|  | const statusSurpriseTotale = [STATUSES.StatusUnconscious, STATUSES.StatusBlind, STATUSES.StatusComma]; | ||||||
|  |  | ||||||
| export class StatusEffects { | export class StatusEffects { | ||||||
|   static onReady() { |   static onReady() { | ||||||
|     const rddStatusIds = rddStatusEffects.map(it => it.id); |     const rddStatusIds = rddStatusEffects.map(it => it.id); | ||||||
|  |     rddStatusEffects.forEach(it => it.flags = { core: { statusId: it.id } }); | ||||||
|     const defaultStatusEffectIds = CONFIG.statusEffects.map(it => it.id); |     const defaultStatusEffectIds = CONFIG.statusEffects.map(it => it.id); | ||||||
|     game.settings.register(SYSTEM_RDD, "use-status-effects", { |     game.settings.register(SYSTEM_RDD, "use-status-effects", { | ||||||
|       name: "use-status-effects", |       name: "use-status-effects", | ||||||
| @@ -47,40 +62,36 @@ export class StatusEffects { | |||||||
|  |  | ||||||
|   static valeurSurprise(effect, isCombat) { |   static valeurSurprise(effect, isCombat) { | ||||||
|     // const id = StatusEffects.statusId(effect); |     // const id = StatusEffects.statusId(effect); | ||||||
|     if (statusSurpriseTotale.has(effect.label)) { |     if (statusSurpriseTotale.includes(effect.flags?.core?.statusId)) { | ||||||
|       return 2; |       return 2; | ||||||
|     } |     } | ||||||
|     return statusDemiSurprise.has(effect.label) || (isCombat && effect.label == demiReveStatusEffect.label) ? 1 : 0; |     return statusDemiSurprise.includes(effect.flags?.core?.statusId) || (isCombat && effect.flags?.core?.statusId == STATUSES.StatusDemiReve) ? 1 : 0; | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static setMandatoryRdd() { |  | ||||||
|     CONFIG.statusEffects.filter(it => statusDemiSurprise.has(it.id) || statusSurpriseTotale.has(it.id)) |  | ||||||
|       .forEach(it => it.rdd = true); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static _getUseStatusEffects() { |   static _getUseStatusEffects() { | ||||||
|     const setting = game.settings.get(SYSTEM_RDD, "use-status-effects"); |     const setting = game.settings.get(SYSTEM_RDD, "use-status-effects"); | ||||||
|     return setting ? new Set(setting.split(',')) : new Set(); |     return setting ? setting.split(',') : []; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static _setUseStatusEffects(useStatusEffects) { |   static _setUseStatusEffects(statusIds) { | ||||||
|     if (game.user.isGM) { |     if (game.user.isGM) { | ||||||
|       game.settings.set(SYSTEM_RDD, "use-status-effects", StatusEffects._toSetting(useStatusEffects)); |       game.settings.set(SYSTEM_RDD, "use-status-effects", StatusEffects._toSetting(statusIds)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     for (let effect of CONFIG.RDD.allEffects) { |     for (let effect of CONFIG.RDD.allEffects) { | ||||||
|       effect.active = effect.rdd || useStatusEffects.has(effect.id); |       effect.active = effect.rdd || statusIds.includes(effect.flags?.core?.statusId); | ||||||
|     } |     } | ||||||
|     CONFIG.statusEffects = CONFIG.RDD.allEffects.filter(it => it.active); |     CONFIG.statusEffects = CONFIG.RDD.allEffects.filter(it => it.active); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static _toSetting(useStatusEffects) { |   static _toSetting(statusIds) { | ||||||
|     return Array.from(useStatusEffects).join(); |     return statusIds.join(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static status(label) { |   static status(statusId) { | ||||||
|     return rddStatusEffects.find(it => it.label == label) ?? { label: label }; |     return rddStatusEffects.find(it => it.flags?.core?.statusId == statusId); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static demiReve() { |   static demiReve() { | ||||||
|     return demiReveStatusEffect; |     return demiReveStatusEffect; | ||||||
|   } |   } | ||||||
| @@ -106,8 +117,10 @@ class StatusEffectsSettings extends FormApplication { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   getData() { |   getData() { | ||||||
|  |     const used = StatusEffects._getUseStatusEffects(); | ||||||
|     let formData = super.getData(); |     let formData = super.getData(); | ||||||
|     formData.effects = CONFIG.RDD.allEffects; |     formData.effects = duplicate(CONFIG.RDD.allEffects); | ||||||
|  |     formData.effects.forEach(it => it.active = used.includes(it.id)) | ||||||
|     return formData; |     return formData; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -118,10 +131,10 @@ class StatusEffectsSettings extends FormApplication { | |||||||
|         let selected = StatusEffects._getUseStatusEffects(); |         let selected = StatusEffects._getUseStatusEffects(); | ||||||
|         let isChecked = event.currentTarget.checked; |         let isChecked = event.currentTarget.checked; | ||||||
|         if (isChecked) { |         if (isChecked) { | ||||||
|           selected.add(id); |           selected.push(id); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|           selected.delete(id); |           selected = selected.filter(it => it != id) | ||||||
|         } |         } | ||||||
|         StatusEffects._setUseStatusEffects(selected); |         StatusEffects._setUseStatusEffects(selected); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -433,9 +433,9 @@ export class TMRRencontres { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async msgEchecPasseurFou(tmrData) { |   static async msgEchecPasseurFou(tmrData) { | ||||||
|     tmrData.sortReserve = tmrData.actor.system.reve.reserve.list[0]; |     tmrData.sortReserve = RdDDice.rollOneOf(tmrData.actor.itemTypes['sortreserve']); | ||||||
|     if (tmrData.sortReserve) { |     if (tmrData.sortReserve) { | ||||||
|       // Passeur fou positionne sur la case d'un ort en réserve // TODO : Choisir le sort le plus loin ou au hasard |       // Passeur fou positionne sur la case d'un sort en réserve | ||||||
|       tmrData.newTMR = TMRUtility.getTMR(tmrData.sortReserve.coord); |       tmrData.newTMR = TMRUtility.getTMR(tmrData.sortReserve.coord); | ||||||
|     } else { |     } else { | ||||||
|       // Déplacement aléatoire de la force du Passeur Fou |       // Déplacement aléatoire de la force du Passeur Fou | ||||||
|   | |||||||
| @@ -379,18 +379,6 @@ export class TMRUtility { | |||||||
|     return await RdDDice.rollOneOf(TMRUtility.filterTMR(filter)) |     return await RdDDice.rollOneOf(TMRUtility.filterTMR(filter)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static getSortsReserve(reserveList, coord) { |  | ||||||
|     // TODO : Gérer les têtes spéciales réserve! |  | ||||||
|     let tmrDescr = this.getTMR(coord); |  | ||||||
|     //console.log("Sort réserve : ", tmrDescr); |  | ||||||
|     if (tmrDescr.type == 'fleuve') { // Gestion de la reserve en Fleuve |  | ||||||
|       return reserveList.filter(it => TMRUtility.getTMR(it.coord).type == 'fleuve'); |  | ||||||
|     } |  | ||||||
|     // Reserve sur un case "normale" |  | ||||||
|     return reserveList.filter(it => it.coord == coord); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   /** Returns a list of case inside a given distance |   /** Returns a list of case inside a given distance | ||||||
|    *  |    *  | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| import { Grammar } from "../grammar.js"; | import { Grammar } from "../grammar.js"; | ||||||
| import { Misc } from "../misc.js"; |  | ||||||
| import { RdDDice } from "../rdd-dice.js"; | import { RdDDice } from "../rdd-dice.js"; | ||||||
| import { TMRUtility } from "../tmr-utility.js"; | import { TMRUtility } from "../tmr-utility.js"; | ||||||
| import { tmrConstants, tmrColors, tmrTokenZIndex } from "../tmr-constants.js"; | import { tmrConstants, tmrColors, tmrTokenZIndex } from "../tmr-constants.js"; | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ export class SortReserve extends Draconique { | |||||||
|   manualMessage() { return false } |   manualMessage() { return false } | ||||||
|   async onActorCreateOwned(actor, item) { } |   async onActorCreateOwned(actor, item) { } | ||||||
|  |  | ||||||
|   code() { return 'sort' } |   code() { return 'sortreserve' } | ||||||
|   tooltip(sort) { return `${sort.name}, r${sort.data.ptreve_reel}` } |   tooltip(sort) { return `${sort.name}, r${sort.system.ptreve}` } | ||||||
|   img() { return 'systems/foundryvtt-reve-de-dragon/icons/tmr/scroll.webp' } |   img() { return 'systems/foundryvtt-reve-de-dragon/icons/tmr/scroll.webp' } | ||||||
|  |  | ||||||
|   createSprite(pixiTMR) { |   createSprite(pixiTMR) { | ||||||
|   | |||||||
| @@ -576,7 +576,7 @@ | |||||||
|   "types": ["objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle",  |   "types": ["objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle",  | ||||||
|             "tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique",  |             "tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique",  | ||||||
|             "musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "signedraconique", "gemme",  |             "musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "signedraconique", "gemme",  | ||||||
|             "possession" ], |             "possession", "sortreserve" ], | ||||||
|   "possession": { |   "possession": { | ||||||
|     "typepossession": "", |     "typepossession": "", | ||||||
|     "possede": false, |     "possede": false, | ||||||
| @@ -889,7 +889,7 @@ | |||||||
|     "descriptionmj": "" |     "descriptionmj": "" | ||||||
|   }, |   }, | ||||||
|   "oeuvre": { |   "oeuvre": { | ||||||
|     "default_carac": "", |     "default_carac": "",   | ||||||
|     "competence": "", |     "competence": "", | ||||||
|     "niveau": 0, |     "niveau": 0, | ||||||
|     "reference": "", |     "reference": "", | ||||||
| @@ -943,6 +943,14 @@ | |||||||
|     }, |     }, | ||||||
|     "description": "", |     "description": "", | ||||||
|     "descriptionmj": "" |     "descriptionmj": "" | ||||||
|  |   }, | ||||||
|  |   "sortreserve": { | ||||||
|  |     "sortid" : "", | ||||||
|  |     "draconic": "", | ||||||
|  |     "coord": "", | ||||||
|  |     "ptreve": 0, | ||||||
|  |     "heurecible": "", | ||||||
|  |     "echectotal": false | ||||||
|   } |   } | ||||||
| } | } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| {{#if calc.surprise}}{{calc.surprise}}! {{/if}} | {{#if calc.surprise}}{{calc.surprise}}! {{/if}} | ||||||
| {{#if effects}} | {{#if effects}} | ||||||
| {{#each effects as |effect key|}} | {{#each effects as |effect key|}} | ||||||
| <span class="active-effect" data-id="{{effect._id}}"> | <span class="active-effect" data-effect="{{effect.flags.core.statusId}}"> | ||||||
|   <img class="button-effect-img delete-active-effect" src="{{effect.icon}}" alt="{{localize effect.label}}" width="24" height="24" /> |   <img class="button-effect-img delete-active-effect" src="{{effect.icon}}" alt="{{localize effect.label}}" width="24" height="24" /> | ||||||
| </span> | </span> | ||||||
| {{/each}} | {{/each}} | ||||||
|   | |||||||
| @@ -569,17 +569,27 @@ | |||||||
|               </li> |               </li> | ||||||
|               {{/each}} |               {{/each}} | ||||||
|             </ul> |             </ul> | ||||||
|           {{/if}} |             {{/if}} | ||||||
|           {{#if hautreve.sortsReserve.length}} |             {{#if sortsReserve.length}} | ||||||
|             <h3>Sorts en Réserve:</h3> |             <h3>Sorts en Réserve:</h3> | ||||||
|             <ul class="item-list alterne-list"> |             <ul class="item-list alterne-list"> | ||||||
|  |               {{#each sortsReserve as |sort key|}} | ||||||
|  |               <li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}"> | ||||||
|  |                 <img class="sheet-competence-img" src="{{sort.img}}" /> | ||||||
|  |                 <span class="display-label"><a>{{#if sort.system.echectotal}}Echec total: {{/if}}{{sort.name}} r{{sort.system.ptreve}}</a></span>  | ||||||
|  |                 <span>{{sort.system.coord}} - {{caseTmr-label sort.system.coord}}</span>  | ||||||
|  |                 <div class="item-controls flex-shrink"> | ||||||
|  |                   <a class="item-delete flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||||
|  |                 </div> | ||||||
|  |               </li> | ||||||
|  |               {{/each}} | ||||||
|               {{#each hautreve.sortsReserve as |reserve key|}} |               {{#each hautreve.sortsReserve as |reserve key|}} | ||||||
|               <li class="item list-item flexrow" data-index="{{key}}"> |               <li class="item list-item flexrow" data-index="{{key}}"> | ||||||
|                 <img class="sheet-competence-img" src="{{reserve.sort.img}}" /> |                 <img class="sheet-competence-img" src="{{reserve.sort.img}}" /> | ||||||
|                 <span class="display-label">{{reserve.sort.name}} r{{reserve.sort.system.ptreve_reel}}</span>  |                 <span class="display-label">{{reserve.sort.name}} r{{reserve.sort.system.ptreve_reel}}</span>  | ||||||
|                 <span>{{reserve.coord}} - {{caseTmr-label reserve.coord}}</span>  |                 <span>{{reserve.coord}} - {{caseTmr-label reserve.coord}}</span>  | ||||||
|                 <div class="item-controls flex-shrink"> |                 <div class="item-controls flex-shrink"> | ||||||
|                   <a class="sort-reserve-delete flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a> |                   <a class="delete-sort-reserve flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||||
|                 </div> |                 </div> | ||||||
|               </li> |               </li> | ||||||
|               {{/each}} |               {{/each}} | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| <form class="dialog-roll-sort"> | <form class="dialog-roll-sort"> | ||||||
|   <h2>Lancer le <span class="sort-ou-rituel">{{#if sort.system.isrituel}}rituel{{else}}sort{{/if}}</span>: |   <h2 class="flexrow">Lancer le {{#if sort.system.isrituel}}rituel{{else}}sort{{/if}}: | ||||||
|     <select name="sort" class="roll-sort flex-grow" data-dtype="String"> |     <select name="sort" class="roll-sort" data-dtype="String"> | ||||||
|       {{#select sort}} |       {{#select sort}} | ||||||
|       {{#each sortList as |sort key|}} |       {{#each sortList as |sort key|}} | ||||||
|       <option value={{key}}>{{this.name}} - {{#if this.system.caseTMRspeciale}} {{this.system.caseTMRspeciale}} |       <option value={{key}}>{{this.name}} - {{#if this.system.caseTMRspeciale}} {{this.system.caseTMRspeciale}} | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
|   {{!-- Sheet Body --}} |   {{!-- Sheet Body --}} | ||||||
|   <section class="sheet-body"> |   <section class="sheet-body"> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label>Draconic </label> |       <label>Draconic</label> | ||||||
|       <select name="system.draconic" id="draconic" data-dtype="String"> |       <select name="system.draconic" id="draconic" data-dtype="String"> | ||||||
|         {{#select system.draconic}} |         {{#select system.draconic}} | ||||||
|         {{>"systems/foundryvtt-reve-de-dragon/templates/sort-draconic.html"}} |         {{>"systems/foundryvtt-reve-de-dragon/templates/sort-draconic.html"}} | ||||||
| @@ -11,7 +11,7 @@ | |||||||
|       </select> |       </select> | ||||||
|     </div>       |     </div>       | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">Case TMR </label> |       <label for="system.caseTMR">Case TMR</label> | ||||||
|       <select name="system.caseTMR" id="caseTMR" data-dtype="String"> |       <select name="system.caseTMR" id="caseTMR" data-dtype="String"> | ||||||
|         {{#select system.caseTMR}} |         {{#select system.caseTMR}} | ||||||
|         {{>"systems/foundryvtt-reve-de-dragon/templates/sort-tmr.html"}} |         {{>"systems/foundryvtt-reve-de-dragon/templates/sort-tmr.html"}} | ||||||
| @@ -20,49 +20,49 @@ | |||||||
|       </select> |       </select> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">Case TMR Spéciale </label> |       <label for="system.caseTMRspeciale">Case TMR Spéciale</label> | ||||||
|       <input class="attribute-value" type="text" name="system.caseTMRspeciale" value="{{system.caseTMRspeciale}}" data-dtype="String"/> |       <input class="attribute-value" type="text" name="system.caseTMRspeciale" value="{{system.caseTMRspeciale}}" data-dtype="String"/> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">Difficulté </label> |       <label for="system.difficulte">Difficulté</label> | ||||||
|       <input class="attribute-value" type="text" name="system.difficulte" value="{{system.difficulte}}" data-dtype="String"/> |       <input class="attribute-value" type="text" name="system.difficulte" value="{{system.difficulte}}" data-dtype="String"/> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">Coût en Rêve </label> |       <label for="system.ptreve">Coût en Rêve</label> | ||||||
|       <input class="attribute-value" type="text" name="system.ptreve" value="{{system.ptreve}}" data-dtype="String"/> |       <input class="attribute-value" type="text" name="system.ptreve" value="{{system.ptreve}}" data-dtype="String"/> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">Coût en Seuil </label> |       <label for="system.coutseuil">Coût en Seuil</label> | ||||||
|       <input class="attribute-value" type="text" name="system.coutseuil" value="{{system.coutseuil}}" data-dtype="Number"/> |       <input class="attribute-value" type="text" name="system.coutseuil" value="{{system.coutseuil}}" data-dtype="Number"/> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="rituel">Rituel </label> |       <label for="system.isrituel">Rituel</label> | ||||||
|       <input class="attribute-value" type="checkbox" name="system.isrituel"  {{#if system.isrituel}}checked{{/if}}/> |       <input class="attribute-value" type="checkbox" name="system.isrituel"  {{#if system.isrituel}}checked{{/if}}/> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">Durée </label> |       <label for="system.duree">Durée</label> | ||||||
|       <input class="attribute-value" type="text" name="system.duree" value="{{system.duree}}" data-dtype="String"/> |       <input class="attribute-value" type="text" name="system.duree" value="{{system.duree}}" data-dtype="String"/> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">Portée </label> |       <label for="system.portee">Portée</label> | ||||||
|       <input class="attribute-value" type="text" name="system.portee" value="{{system.portee}}" data-dtype="String"/> |       <input class="attribute-value" type="text" name="system.portee" value="{{system.portee}}" data-dtype="String"/> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">Cible </label> |       <label for="system.cible">Cible</label> | ||||||
|       <input class="attribute-value" type="text" name="system.cible" value="{{system.cible}}" data-dtype="String"/> |       <input class="attribute-value" type="text" name="system.cible" value="{{system.cible}}" data-dtype="String"/> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">Jet de Resistance</label> |       <label for="system.JR">Jet de Resistance</label> | ||||||
|       <input class="attribute-value" type="text" name="system.JR" value="{{system.JR}}" data-dtype="String"/> |       <input class="attribute-value" type="text" name="system.JR" value="{{system.JR}}" data-dtype="String"/> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="xp">XP </label> |       <label for="system.xp">XP</label> | ||||||
|       <input class="attribute-value" type="text" name="system.xp" value="{{system.xp}}" data-dtype="Number"/> |       <input class="attribute-value" type="text" name="system.xp" value="{{system.xp}}" data-dtype="Number"/> | ||||||
|     </div> |     </div> | ||||||
|     {{#if owner}} |     {{#if owner}} | ||||||
|     {{#each bonusCaseList as |bcData key|}} |     {{#each bonusCaseList as |bcData key|}} | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <label for="bonuscase">Case/Bonus :</label> |       <label for="caseValue">Case/Bonus :</label> | ||||||
|       <input class="attribute-value"  type="text" name="caseValue" value="{{bcData.case}}" data-dtype="String"/> |       <input class="attribute-value"  type="text" name="caseValue" value="{{bcData.case}}" data-dtype="String"/> | ||||||
|       <input class="attribute-value" type="text" name="bonusValue" value="{{bcData.bonus}}" data-dtype="Number"/> |       <input class="attribute-value" type="text" name="bonusValue" value="{{bcData.bonus}}" data-dtype="Number"/> | ||||||
|     </div> |     </div> | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								templates/item-sortreserve-sheet.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								templates/item-sortreserve-sheet.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | <form class="{{cssClass}}" autocomplete="off"> | ||||||
|  |   {{>"systems/foundryvtt-reve-de-dragon/templates/header-item.html"}} | ||||||
|  |  | ||||||
|  |   <section class="sheet-body"> | ||||||
|  |     {{#if (and system.sortid sort)}} | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label>Sort</label> | ||||||
|  |       <label>{{sort.name}} - {{sort.system.draconic}} / {{sort.system.difficulte}}</label> | ||||||
|  |     </div> | ||||||
|  |     {{else}} | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label>Draconic</label> | ||||||
|  |       <select name="system.draconic" id="draconic" data-dtype="String"> | ||||||
|  |         {{#select system.draconic}} | ||||||
|  |         {{>"systems/foundryvtt-reve-de-dragon/templates/sort-draconic.html"}} | ||||||
|  |         {{/select}} | ||||||
|  |       </select> | ||||||
|  |     </div> | ||||||
|  |     {{/if}} | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="system.coord">Case TMR</label> | ||||||
|  |       <input class="attribute-value" type="text" name="system.coord" value="{{system.coord}}" data-dtype="String"/> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="system.ptreve">Rêve</label> | ||||||
|  |       <input class="attribute-value" type="text" name="system.ptreve" value="{{system.ptreve}}" data-dtype="String"/> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="system.heurecible">Heure de naissance cible</label> | ||||||
|  |       <select type="text" name="system.heurecible" value="{{system.heurecible}}" data-dtype="String"> | ||||||
|  |         {{#select system.heurecible}} | ||||||
|  |         {{>"systems/foundryvtt-reve-de-dragon/templates/heures-select-option.html"}} | ||||||
|  |         {{/select}} | ||||||
|  |       </select> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="system.echectotal">Echec total</label> | ||||||
|  |       <input class="attribute-value" type="checkbox" name="system.echectotal" {{#if system.echectotal}}checked{{/if}} /> | ||||||
|  |     </div> | ||||||
|  |   </section> | ||||||
|  | </form> | ||||||
| @@ -7,7 +7,7 @@ | |||||||
|       {{else}} |       {{else}} | ||||||
|       <input class="resource-content select-effect" type="checkbox" name="{{effect.id}}" {{#if effect.active}}checked{{/if}}/> |       <input class="resource-content select-effect" type="checkbox" name="{{effect.id}}" {{#if effect.active}}checked{{/if}}/> | ||||||
|       {{/if}} |       {{/if}} | ||||||
|       <img class="button-effect-img" height="16" width="16" src="{{effect.icon}}" alt="{{ localize  effect.label}}" /> |       <img class="button-effect-img" height="16" width="16" src="{{effect.icon}}" alt="{{localize effect.label}}" /> | ||||||
|       <label>{{localize effect.label}}</label> |       <label>{{localize effect.label}}</label> | ||||||
|     </li> |     </li> | ||||||
|     {{/each}} |     {{/each}} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user