Initial import
This commit is contained in:
commit
db5fbb0e63
7
LICENSE.txt
Normal file
7
LICENSE.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Copyright 2023 Open Sesame Games
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
42
README.md
Normal file
42
README.md
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Te Deum Pour Un Massacre for FoundryVTT (French RPG, Open Sesam Games, Official)s
|
||||||
|
|
||||||
|
|
||||||
|
This is a base game system with functionnal character sheets for the game Ecryme, powered by the Engrenage system.
|
||||||
|
You can join the kickstarter and obtain the base books here : https://www.kickstarter.com/projects/osg-us/ecryme
|
||||||
|
|
||||||
|
# System overview
|
||||||
|
|
||||||
|
|
||||||
|
The game system in Foundry offers the following features :
|
||||||
|
- PC/NPC sheet
|
||||||
|
- Skill rolls
|
||||||
|
- Cephaly rolls (with Anency support)
|
||||||
|
- Confrontation management, with detailed result in the chat card
|
||||||
|
- Weapon rolls
|
||||||
|
- Trait management, with Spleen and Ideal also.
|
||||||
|
- Compendiums of items for the game
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
# Contributions
|
||||||
|
|
||||||
|
- Original code realised by Uberwald (https://www.uberwald.me/)
|
||||||
|
|
||||||
|
|
||||||
|
# English translation
|
||||||
|
|
||||||
|
English translation by Conal Longden and Ian McClung
|
||||||
|
|
||||||
|
# Copyright mentions
|
||||||
|
|
||||||
|
Copyright 2023 Open Sesame Games
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Ecryme is a game written by Alexandre Clavel and Samuel Metzener, in a universe created by Mathieu gaborit. All of the aforementionned authors retain there moral rights regarding this work in both print and digital formats.
|
||||||
|
|
||||||
|
# Requests or Problems
|
||||||
|
|
||||||
|
Please report any requests or problems you have at contact@open-sesame.games
|
17
changelog.md
Normal file
17
changelog.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
v11.0.36
|
||||||
|
|
||||||
|
- Enable deletion specialization
|
||||||
|
- Custome bonus for specializations
|
||||||
|
- Specialization direct rolls
|
||||||
|
|
||||||
|
v11.0.31
|
||||||
|
|
||||||
|
Add profession, fix equipment tab and add missing translation
|
||||||
|
|
||||||
|
v11.0.30
|
||||||
|
|
||||||
|
Snapshot and more detailed README
|
||||||
|
|
||||||
|
v11.0.28
|
||||||
|
|
||||||
|
Initial release
|
BIN
fonts/MailartRubberstamp-Regular.otf
Normal file
BIN
fonts/MailartRubberstamp-Regular.otf
Normal file
Binary file not shown.
BIN
fonts/MailartRubberstamp-Regular.woff
Normal file
BIN
fonts/MailartRubberstamp-Regular.woff
Normal file
Binary file not shown.
25
gulpfile.js
Normal file
25
gulpfile.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
var gulp = require('gulp');
|
||||||
|
|
||||||
|
var postcss = require('gulp-postcss');
|
||||||
|
|
||||||
|
var autoprefixer = require('autoprefixer');
|
||||||
|
var cssnext = require('cssnext');
|
||||||
|
var precss = require('precss');
|
||||||
|
|
||||||
|
gulp.task('css', function () {
|
||||||
|
|
||||||
|
var processors = [
|
||||||
|
autoprefixer,
|
||||||
|
cssnext,
|
||||||
|
precss
|
||||||
|
];
|
||||||
|
|
||||||
|
return gulp.src('./postcss/*.css')
|
||||||
|
.pipe(postcss(processors))
|
||||||
|
.pipe(gulp.dest('./styles'));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function watchUpdates() {
|
||||||
|
gulp.watch('./postcss/*.css', css);
|
||||||
|
}
|
5
images/icons/.directory
Normal file
5
images/icons/.directory
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[Dolphin]
|
||||||
|
SortRole=modificationtime
|
||||||
|
Timestamp=2023,5,10,17,7,42.817
|
||||||
|
Version=4
|
||||||
|
VisibleRoles=Details_text,Details_size,Details_modificationtime,Details_creationtime,CustomizedDetails
|
175
lang/fr.json
Normal file
175
lang/fr.json
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
{
|
||||||
|
"TYPES": {
|
||||||
|
"Actor":{
|
||||||
|
"pc": "Personnage Joueur",
|
||||||
|
"npc": "Personnage Non Joueur",
|
||||||
|
"annency": "Anence"
|
||||||
|
},
|
||||||
|
"Item": {
|
||||||
|
"trait": "Trait",
|
||||||
|
"weapon": "Arme",
|
||||||
|
"equipment": "Equipement",
|
||||||
|
"maneuver": "Manoeuvre",
|
||||||
|
"specialization": "Spécialisation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ECRY": {
|
||||||
|
"settings": {
|
||||||
|
"cogs": "Engrenages",
|
||||||
|
"cephaly": "Céphalie",
|
||||||
|
"boheme": "Bohême",
|
||||||
|
"amertume": "Amertume",
|
||||||
|
"gamelevel": "Niveau de jeu"
|
||||||
|
},
|
||||||
|
"chat": {
|
||||||
|
"formula": "Formule",
|
||||||
|
"difficulty": "Difficulté",
|
||||||
|
"dicesum": "Dés",
|
||||||
|
"result": "Resultat",
|
||||||
|
"margin": "Marge",
|
||||||
|
"success": "Succés!",
|
||||||
|
"failure": "Echec!",
|
||||||
|
"specialization": "Spécialisation",
|
||||||
|
"traitbonus": "Trait bonus",
|
||||||
|
"traitmalus": "Trait malus",
|
||||||
|
"bonusmalustraits": "Bonus/Malus des Traits",
|
||||||
|
"spectranscend": "Dépassement de soi : ",
|
||||||
|
"confrontselected": "Confrontation selectionnée",
|
||||||
|
"sentogm": "La confrontation a été envoyée au MJ"
|
||||||
|
},
|
||||||
|
"rule": {
|
||||||
|
"cephaly-success-12": "Durée : 1 scène - Impact : Superficiel - Bonus : 1 - Elegie : 1",
|
||||||
|
"cephaly-success-4": "Durée : 1 semaine - Impact : Léger - Bonus : 2 - Elegie : 2",
|
||||||
|
"cephaly-success-6": "Durée : 1 mois - Impact : Grave - Bonus : 3 - Elegie : 3",
|
||||||
|
"cephaly-success-8": "Durée : 1 année - Impact : Majeur - Bonus : 4 - Elegie : 4",
|
||||||
|
"cephaly-success-10": "Durée : Permanent - Impact : Mort - Bonus : 5 - Elegie : 5",
|
||||||
|
"cephaly-failure-2": "Durée : 1 scène - Impact : Superficiel - Malus : 1 - Symptôme non visible et sans gravité - Altération bégigne difficilement repérable",
|
||||||
|
"cephaly-failure-4": "Durée : 1 semaine - Impact : Léger - Malus : 2 - Symptôme visible non incapacitant - Altération repérable",
|
||||||
|
"cephaly-failure-6": "Durée : 1 mois - Impact : Grave - Malus : 3 - Symptôme incapacitant - Altération repérable et fâcheuse",
|
||||||
|
"cephaly-failure-8": "Durée : 1 année - Impact : Majeur - Malus : 4 - Symptôme très incapacitant - Altération dangereuse",
|
||||||
|
"cephaly-failure-10": "Durée : Permanent - Impact : Mort/Folie - Malus : 5 - Symptôme spectaculaire et repoussant - Altération dangereuse globalement"
|
||||||
|
|
||||||
|
},
|
||||||
|
"warn": {
|
||||||
|
"notenoughdice": "L'Accomplissement et la Préservation doivent avoir 2 dés chacun"
|
||||||
|
},
|
||||||
|
"ui": {
|
||||||
|
"equipmentfree": "Equipements (saisie libre)",
|
||||||
|
"traitType": "Type de trait",
|
||||||
|
"niveauTrait": "Niveau du trait",
|
||||||
|
"effect": "Incidence",
|
||||||
|
"weight": "Poids",
|
||||||
|
"cost": "Prix",
|
||||||
|
"costUnit": "Unité",
|
||||||
|
"ingot": "Lingot",
|
||||||
|
"ingotin": "Lingotin",
|
||||||
|
"goldcoin": "Pièce d'or",
|
||||||
|
"lige": "Lige",
|
||||||
|
"hurle": "Hurle",
|
||||||
|
"coin": "Sous",
|
||||||
|
"notes": "Notes",
|
||||||
|
"bio": "Bio",
|
||||||
|
"bionotes": "Bio&Notes",
|
||||||
|
"skills": "Compétences",
|
||||||
|
"traits": "Traits",
|
||||||
|
"equipment": "Equipement",
|
||||||
|
"physical": "Physiques",
|
||||||
|
"mental": "Mentales",
|
||||||
|
"social": "Sociales",
|
||||||
|
"athletics": "Athlétisme",
|
||||||
|
"driving": "Conduite",
|
||||||
|
"fencing": "Escrime",
|
||||||
|
"brawling": "Pugilat",
|
||||||
|
"shooting": "Tir",
|
||||||
|
"anthropomecanology": "Anthropo-Mécanologie",
|
||||||
|
"ecrymology": "Écrymologie",
|
||||||
|
"traumatology": "Traumatologie",
|
||||||
|
"traversology": "Traversologie",
|
||||||
|
"urbatechnology": "Urbatechnologie",
|
||||||
|
"quibbling": "Argutie",
|
||||||
|
"creativity": "Créativité",
|
||||||
|
"loquacity": "Faconde",
|
||||||
|
"guile": "Maraude",
|
||||||
|
"performance" :"Représentation",
|
||||||
|
"skill": "Compétence",
|
||||||
|
"troublesome": "Malaisé",
|
||||||
|
"occasional": "Peu frequent",
|
||||||
|
"difficult": "Difficile",
|
||||||
|
"uncommon": "Atypique",
|
||||||
|
"verydifficult": "Très difficile",
|
||||||
|
"rare": "Rare",
|
||||||
|
"extremdifficult": "Extrêmement difficile",
|
||||||
|
"veryrare": "Très rare",
|
||||||
|
"increddifficult": "Incroyable",
|
||||||
|
"exceptrare": "Exceptionnel",
|
||||||
|
"none": "Aucun",
|
||||||
|
"roll": "Lancer les dés !",
|
||||||
|
"cancel": "Annuler",
|
||||||
|
"rolltitle": "Ou l'on teste ses compétences",
|
||||||
|
"spec": "Spécialisation",
|
||||||
|
"traitbonus": "Traits bonus",
|
||||||
|
"traitmalus": "Traits malus",
|
||||||
|
"applyideal": "Utiliser l'idéal",
|
||||||
|
"applyspleen": "Utiliser le spleen",
|
||||||
|
"skilltranscendence": "Dépassement de soi",
|
||||||
|
"confrontation": "Confrontation",
|
||||||
|
"rollnormal": "Normal (4d6)",
|
||||||
|
"rollspleen": "Avec le Spleen (5d6, 4 plus bas conservés)",
|
||||||
|
"rollideal": "Avec l'Idéal (5d6, 4 plus haut conservés)",
|
||||||
|
"superficial": "Superficiel",
|
||||||
|
"light": "Léger",
|
||||||
|
"serious": "Grave",
|
||||||
|
"major": "Majeur",
|
||||||
|
"impactType": "Type d'Impact",
|
||||||
|
"impactLevel": "Niveau d'impact",
|
||||||
|
"impactphysical": "Physique",
|
||||||
|
"impactmental": "Mental",
|
||||||
|
"impactsocial": "Social",
|
||||||
|
"impactmalus": "Malus d'Impact",
|
||||||
|
"ongoingconfront": "Confrontations en cours",
|
||||||
|
"confront":"Confrontation",
|
||||||
|
"launchconfront": "Lancer la confrontation",
|
||||||
|
"execution": "Accomplissement",
|
||||||
|
"preservation": "Préservation",
|
||||||
|
"dicepool": "Dés disponibles",
|
||||||
|
"selectconfront": "Sélectionner pour la Confrontation",
|
||||||
|
"transcendapply": "Appliquer la Transcendence à ",
|
||||||
|
"healthcombat": "Santé&Combat",
|
||||||
|
"name": "Nom",
|
||||||
|
"weapons": "Armes",
|
||||||
|
"weapon": "Arme",
|
||||||
|
"melee": "Mêlée",
|
||||||
|
"ranged": "A Distance",
|
||||||
|
"weapontype": "Type d'arme",
|
||||||
|
"type": "Type",
|
||||||
|
"applyimpact": "Appliquer l'impact",
|
||||||
|
"applybonus": "Appliquer le bonus",
|
||||||
|
"bonuspool": "Bonus disponibles",
|
||||||
|
"cephaly": "Cephalie",
|
||||||
|
"elegy": "Elégie",
|
||||||
|
"entelechy": "Entéléchie",
|
||||||
|
"mekany": "Mekanë",
|
||||||
|
"psyche": "Psyché",
|
||||||
|
"scoria": "Scorie",
|
||||||
|
"cephalydifficulty": "Difficulté de la Céphalie",
|
||||||
|
"maneuvers": "Manoeuvres",
|
||||||
|
"annency": "Anence",
|
||||||
|
"iscollective": "Collective",
|
||||||
|
"ismultiple": "Multiple",
|
||||||
|
"description": "Description",
|
||||||
|
"location": "Lieu",
|
||||||
|
"characters": "Personnages",
|
||||||
|
"enhancements": "Améliorations",
|
||||||
|
"oniricform": "Forme Onorique (Bohême)",
|
||||||
|
"ideals": "Idéaux",
|
||||||
|
"politic": "Idéaux politiques",
|
||||||
|
"boheme": "Bohême",
|
||||||
|
"annencybonus": "Bonus d'Anence",
|
||||||
|
"bornplace": "Lieu de naissance",
|
||||||
|
"residence": "Résidence",
|
||||||
|
"origin": "Origine",
|
||||||
|
"childhood": "Enfance",
|
||||||
|
"bonus": "Bonus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
197
modules/actors/tedeum-actor-sheet.js
Normal file
197
modules/actors/tedeum-actor-sheet.js
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/**
|
||||||
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
|
* @extends {ActorSheet}
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { EcrymeUtility } from "../common/tedeum-utility.js";
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
export class EcrymeActorSheet extends ActorSheet {
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static get defaultOptions() {
|
||||||
|
|
||||||
|
return mergeObject(super.defaultOptions, {
|
||||||
|
classes: ["fvtt-ecryme", "sheet", "actor"],
|
||||||
|
template: "systems/fvtt-ecryme/templates/actors/actor-sheet.hbs",
|
||||||
|
width: 860,
|
||||||
|
height:680,
|
||||||
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "skills" }],
|
||||||
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
||||||
|
editScore: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async getData() {
|
||||||
|
|
||||||
|
let formData = {
|
||||||
|
title: this.title,
|
||||||
|
id: this.actor.id,
|
||||||
|
type: this.actor.type,
|
||||||
|
img: this.actor.img,
|
||||||
|
name: this.actor.name,
|
||||||
|
editable: this.isEditable,
|
||||||
|
cssClass: this.isEditable ? "editable" : "locked",
|
||||||
|
system: duplicate(this.object.system),
|
||||||
|
limited: this.object.limited,
|
||||||
|
skills: this.actor.prepareSkills(),
|
||||||
|
traits: this.actor.getRollTraits(),
|
||||||
|
confrontations: this.actor.getConfrontations(),
|
||||||
|
ideal: this.actor.getIdeal(),
|
||||||
|
spleen: this.actor.getSpleen(),
|
||||||
|
impacts: this.object.getImpacts(),
|
||||||
|
config: duplicate(game.system.ecryme.config),
|
||||||
|
weapons: this.actor.getWeapons(),
|
||||||
|
maneuvers: this.actor.getManeuvers(),
|
||||||
|
impactsMalus: this.actor.getImpactsMalus(),
|
||||||
|
archetype: duplicate(this.actor.getArchetype()),
|
||||||
|
equipments: this.actor.getEquipments(),
|
||||||
|
hasCephaly: EcrymeUtility.hasCephaly(),
|
||||||
|
hasBoheme: EcrymeUtility.hasBoheme(),
|
||||||
|
hasAmertume: EcrymeUtility.hasAmertume(),
|
||||||
|
cephalySkills: this.actor.getCephalySkills(),
|
||||||
|
subActors: duplicate(this.actor.getSubActors()),
|
||||||
|
annency: this.actor.getAnnency(),
|
||||||
|
description: await TextEditor.enrichHTML(this.object.system.description, { async: true }),
|
||||||
|
notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }),
|
||||||
|
equipementlibre: await TextEditor.enrichHTML(this.object.system.equipementlibre, { async: true }),
|
||||||
|
options: this.options,
|
||||||
|
owner: this.document.isOwner,
|
||||||
|
editScore: this.options.editScore,
|
||||||
|
isGM: game.user.isGM
|
||||||
|
}
|
||||||
|
this.formData = formData;
|
||||||
|
|
||||||
|
console.log("PC : ", formData, this.object);
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
// Everything below here is only needed if the sheet is editable
|
||||||
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
|
html.bind("keydown", function(e) { // Ignore Enter in actores sheet
|
||||||
|
if (e.keyCode === 13) return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
html.find('.open-annency').click(ev => {
|
||||||
|
let actorId = $(ev.currentTarget).data("annency-id")
|
||||||
|
const actor = game.actors.get(actorId)
|
||||||
|
actor.sheet.render(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Update Inventory Item
|
||||||
|
html.find('.item-edit').click(ev => {
|
||||||
|
const li = $(ev.currentTarget).parents(".item")
|
||||||
|
let itemId = li.data("item-id")
|
||||||
|
const item = this.actor.items.get( itemId );
|
||||||
|
item.sheet.render(true);
|
||||||
|
});
|
||||||
|
// Delete Inventory Item
|
||||||
|
html.find('.item-delete').click(ev => {
|
||||||
|
const li = $(ev.currentTarget).parents(".item")
|
||||||
|
EcrymeUtility.confirmDelete(this, li).catch("Error : No deletion confirmed")
|
||||||
|
})
|
||||||
|
html.find('.item-add').click(ev => {
|
||||||
|
let dataType = $(ev.currentTarget).data("type")
|
||||||
|
this.actor.createEmbeddedDocuments('Item', [{ name: "NewItem", type: dataType }], { renderSheet: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
html.find('.subactor-edit').click(ev => {
|
||||||
|
const li = $(ev.currentTarget).parents(".item");
|
||||||
|
let actorId = li.data("actor-id");
|
||||||
|
let actor = game.actors.get( actorId );
|
||||||
|
actor.sheet.render(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
html.find('.subactor-delete').click(ev => {
|
||||||
|
const li = $(ev.currentTarget).parents(".item");
|
||||||
|
let actorId = li.data("actor-id");
|
||||||
|
this.actor.delSubActor(actorId);
|
||||||
|
});
|
||||||
|
html.find('.quantity-minus').click(event => {
|
||||||
|
const li = $(event.currentTarget).parents(".item");
|
||||||
|
this.actor.incDecQuantity( li.data("item-id"), -1 );
|
||||||
|
} );
|
||||||
|
html.find('.quantity-plus').click(event => {
|
||||||
|
const li = $(event.currentTarget).parents(".item");
|
||||||
|
this.actor.incDecQuantity( li.data("item-id"), +1 );
|
||||||
|
} );
|
||||||
|
|
||||||
|
html.find('.roll-skill').click((event) => {
|
||||||
|
let categKey = $(event.currentTarget).data("category-key")
|
||||||
|
let skillKey = $(event.currentTarget).data("skill-key")
|
||||||
|
this.actor.rollSkill(categKey, skillKey)
|
||||||
|
});
|
||||||
|
html.find('.roll-spec').click((event) => {
|
||||||
|
let categKey = $(event.currentTarget).data("category-key")
|
||||||
|
let skillKey = $(event.currentTarget).data("skill-key")
|
||||||
|
let specId = $(event.currentTarget).data("spec-id")
|
||||||
|
this.actor.rollSpec(categKey, skillKey, specId)
|
||||||
|
});
|
||||||
|
html.find('.roll-skill-confront').click((event) => {
|
||||||
|
let categKey = $(event.currentTarget).data("category-key")
|
||||||
|
let skillKey = $(event.currentTarget).data("skill-key")
|
||||||
|
this.actor.rollSkillConfront(categKey, skillKey)
|
||||||
|
});
|
||||||
|
html.find('.roll-cephaly').click((event) => {
|
||||||
|
let skillKey = $(event.currentTarget).data("skill-key")
|
||||||
|
this.actor.rollCephalySkillConfront(skillKey)
|
||||||
|
});
|
||||||
|
html.find('.roll-weapon-confront').click((event) => {
|
||||||
|
const li = $(event.currentTarget).parents(".item")
|
||||||
|
let weaponId = li.data("item-id");
|
||||||
|
this.actor.rollWeaponConfront(weaponId)
|
||||||
|
});
|
||||||
|
|
||||||
|
html.find('.impact-modify').click((event) => {
|
||||||
|
let impactType = $(event.currentTarget).data("impact-type")
|
||||||
|
let impactLevel = $(event.currentTarget).data("impact-level")
|
||||||
|
let modifier = Number($(event.currentTarget).data("impact-modifier"))
|
||||||
|
this.actor.modifyImpact(impactType, impactLevel, modifier)
|
||||||
|
});
|
||||||
|
|
||||||
|
html.find('.roll-weapon').click((event) => {
|
||||||
|
const armeId = $(event.currentTarget).data("arme-id")
|
||||||
|
this.actor.rollArme(armeId)
|
||||||
|
});
|
||||||
|
|
||||||
|
html.find('.lock-unlock-sheet').click((event) => {
|
||||||
|
this.options.editScore = !this.options.editScore;
|
||||||
|
this.render(true);
|
||||||
|
});
|
||||||
|
html.find('.item-equip').click(ev => {
|
||||||
|
const li = $(ev.currentTarget).parents(".item");
|
||||||
|
this.actor.equipItem( li.data("item-id") );
|
||||||
|
this.render(true);
|
||||||
|
});
|
||||||
|
html.find('.update-field').change(ev => {
|
||||||
|
const fieldName = $(ev.currentTarget).data("field-name");
|
||||||
|
let value = Number(ev.currentTarget.value);
|
||||||
|
this.actor.update( { [`${fieldName}`]: value } );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
setPosition(options = {}) {
|
||||||
|
const position = super.setPosition(options);
|
||||||
|
const sheetBody = this.element.find(".sheet-body");
|
||||||
|
const bodyHeight = position.height - 192;
|
||||||
|
sheetBody.css("height", bodyHeight);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
_updateObject(event, formData) {
|
||||||
|
// Update the Actor
|
||||||
|
return this.object.update(formData);
|
||||||
|
}
|
||||||
|
}
|
505
modules/actors/tedeum-actor.js
Normal file
505
modules/actors/tedeum-actor.js
Normal file
@ -0,0 +1,505 @@
|
|||||||
|
/* -------------------------------------------- */
|
||||||
|
import { EcrymeUtility } from "../common/ecryme-utility.js";
|
||||||
|
import { EcrymeRollDialog } from "../dialogs/ecryme-roll-dialog.js";
|
||||||
|
import { EcrymeConfrontStartDialog } from "../dialogs/ecryme-confront-start-dialog.js";
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
|
||||||
|
* @extends {Actor}
|
||||||
|
*/
|
||||||
|
export class EcrymeActor extends Actor {
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Override the create() function to provide additional SoS functionality.
|
||||||
|
*
|
||||||
|
* This overrided create() function adds initial items
|
||||||
|
* Namely: Basic skills, money,
|
||||||
|
*
|
||||||
|
* @param {Object} data Barebones actor data which this function adds onto.
|
||||||
|
* @param {Object} options (Unused) Additional options which customize the creation workflow.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static async create(data, options) {
|
||||||
|
|
||||||
|
// Case of compendium global import
|
||||||
|
if (data instanceof Array) {
|
||||||
|
return super.create(data, options);
|
||||||
|
}
|
||||||
|
// If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
|
||||||
|
if (data.items) {
|
||||||
|
let actor = super.create(data, options);
|
||||||
|
return actor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.create(data, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async prepareData() {
|
||||||
|
super.prepareData()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
prepareDerivedData() {
|
||||||
|
super.prepareDerivedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_preUpdate(changed, options, user) {
|
||||||
|
|
||||||
|
super._preUpdate(changed, options, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async _preCreate(data, options, user) {
|
||||||
|
await super._preCreate(data, options, user);
|
||||||
|
|
||||||
|
// Configure prototype token settings
|
||||||
|
const prototypeToken = {};
|
||||||
|
if (this.type === "pc") Object.assign(prototypeToken, {
|
||||||
|
sight: { enabled: true }, actorLink: true, disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY
|
||||||
|
});
|
||||||
|
this.updateSource({ prototypeToken });
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getMoneys() {
|
||||||
|
let comp = this.items.filter(item => item.type == 'money');
|
||||||
|
EcrymeUtility.sortArrayObjectsByName(comp)
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
getArchetype() {
|
||||||
|
let comp = duplicate(this.items.find(item => item.type == 'archetype') || { name: "Pas d'archetype" })
|
||||||
|
if (comp?.system) {
|
||||||
|
comp.tarot = EcrymeUtility.getTarot(comp.system.lametutelaire)
|
||||||
|
}
|
||||||
|
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
buildAnnencyActorList() {
|
||||||
|
let membersFull = {}
|
||||||
|
for(let id of this.system.base.characters) {
|
||||||
|
let actor = game.actors.get(id)
|
||||||
|
membersFull[id] = { name: actor.name, id: actor.id, img: actor.img }
|
||||||
|
}
|
||||||
|
return membersFull
|
||||||
|
}
|
||||||
|
/* ----------------------- --------------------- */
|
||||||
|
addAnnencyActor(actorId) {
|
||||||
|
let members = duplicate(this.system.base.characters)
|
||||||
|
members.push(actorId)
|
||||||
|
this.update({ 'system.base.characters': members })
|
||||||
|
}
|
||||||
|
async removeAnnencyActor(actorId) {
|
||||||
|
let members = this.system.base.characters.filter(id => id != actorId)
|
||||||
|
this.update({ 'system.base.characters': members })
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getAnnency() {
|
||||||
|
return game.actors.find(a => a.type == 'annency' && a.system.base.characters.includes(this.id))
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getConfrontations() {
|
||||||
|
return this.items.filter(it => it.type == "confrontation")
|
||||||
|
}
|
||||||
|
getRollTraits() {
|
||||||
|
return this.items.filter(it => it.type == "trait" && it.system.traitype == "normal")
|
||||||
|
}
|
||||||
|
getIdeal() {
|
||||||
|
return this.items.find(it => it.type == "trait" && it.system.traitype == "ideal")
|
||||||
|
}
|
||||||
|
getSpleen() {
|
||||||
|
return this.items.find(it => it.type == "trait" && it.system.traitype == "spleen")
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getTrait(id) {
|
||||||
|
//console.log("TRAITS", this.items, this.items.filter(it => it.type == "trait") )
|
||||||
|
return this.items.find(it => it.type == "trait" && it._id == id)
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getSpecialization(id) {
|
||||||
|
let spec = this.items.find(it => it.type == "specialization" && it.id == id)
|
||||||
|
return spec
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getSpecializations(skillKey) {
|
||||||
|
return this.items.filter(it => it.type == "specialization" && it.system.skillkey == skillKey)
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
prepareSkills() {
|
||||||
|
let skills = duplicate(this.system.skills)
|
||||||
|
for (let categKey in skills) {
|
||||||
|
let category = skills[categKey]
|
||||||
|
for (let skillKey in category.skilllist) {
|
||||||
|
let skill = category.skilllist[skillKey]
|
||||||
|
skill.spec = this.getSpecializations(skillKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skills
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getCephalySkills() {
|
||||||
|
let skills = duplicate(this.system.cephaly.skilllist)
|
||||||
|
return skills
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getImpacts() {
|
||||||
|
let comp = duplicate(this.items.filter(item => item.type == 'impact') || [])
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getWeapons() {
|
||||||
|
let comp = duplicate(this.items.filter(item => item.type == 'weapon') || [])
|
||||||
|
EcrymeUtility.sortArrayObjectsByName(comp)
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
getManeuvers() {
|
||||||
|
let comp = duplicate(this.items.filter(item => item.type == 'maneuver') || [])
|
||||||
|
EcrymeUtility.sortArrayObjectsByName(comp)
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getItemById(id) {
|
||||||
|
let item = this.items.find(item => item.id == id);
|
||||||
|
if (item) {
|
||||||
|
item = duplicate(item)
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async equipItem(itemId) {
|
||||||
|
let item = this.items.find(item => item.id == itemId)
|
||||||
|
if (item?.system) {
|
||||||
|
if (item.type == "armor") {
|
||||||
|
let armor = this.items.find(item => item.id != itemId && item.type == "armor" && item.system.equipped)
|
||||||
|
if (armor) {
|
||||||
|
ui.notifications.warn("You already have an armor equipped!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item.type == "shield") {
|
||||||
|
let shield = this.items.find(item => item.id != itemId && item.type == "shield" && item.system.equipped)
|
||||||
|
if (shield) {
|
||||||
|
ui.notifications.warn("You already have a shield equipped!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let update = { _id: item.id, "system.equipped": !item.system.equipped };
|
||||||
|
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------- */
|
||||||
|
getEquipments() {
|
||||||
|
return this.items.filter(item => item.type == 'equipment')
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------- */
|
||||||
|
async buildContainerTree() {
|
||||||
|
let equipments = duplicate(this.items.filter(item => item.type == "equipment") || [])
|
||||||
|
for (let equip1 of equipments) {
|
||||||
|
if (equip1.system.iscontainer) {
|
||||||
|
equip1.system.contents = []
|
||||||
|
equip1.system.contentsEnc = 0
|
||||||
|
for (let equip2 of equipments) {
|
||||||
|
if (equip1._id != equip2.id && equip2.system.containerid == equip1.id) {
|
||||||
|
equip1.system.contents.push(equip2)
|
||||||
|
let q = equip2.system.quantity ?? 1
|
||||||
|
equip1.system.contentsEnc += q * equip2.system.weight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute whole enc
|
||||||
|
let enc = 0
|
||||||
|
for (let item of equipments) {
|
||||||
|
//item.data.idrDice = EcrymeUtility.getDiceFromLevel(Number(item.data.idr))
|
||||||
|
if (item.system.equipped) {
|
||||||
|
if (item.system.iscontainer) {
|
||||||
|
enc += item.system.contentsEnc
|
||||||
|
} else if (item.system.containerid == "") {
|
||||||
|
let q = item.system.quantity ?? 1
|
||||||
|
enc += q * item.system.weight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let item of this.items) { // Process items/shields/armors
|
||||||
|
if ((item.type == "weapon" || item.type == "shield" || item.type == "armor") && item.system.equipped) {
|
||||||
|
let q = item.system.quantity ?? 1
|
||||||
|
enc += q * item.system.weight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store local values
|
||||||
|
this.encCurrent = enc
|
||||||
|
this.containersTree = equipments.filter(item => item.system.containerid == "") // Returns the root of equipements without container
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async equipGear(equipmentId) {
|
||||||
|
let item = this.items.find(item => item.id == equipmentId);
|
||||||
|
if (item?.system) {
|
||||||
|
let update = { _id: item.id, "system.equipped": !item.system.equipped };
|
||||||
|
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
modifyImpact(impactType, impactLevel, modifier) {
|
||||||
|
console.log(impactType, impactLevel, modifier)
|
||||||
|
let current = this.system.impacts[impactType][impactLevel]
|
||||||
|
if (modifier > 0) {
|
||||||
|
while ( EcrymeUtility.getImpactMax(impactLevel) == current && impactLevel != "major") {
|
||||||
|
impactLevel = EcrymeUtility.getNextImpactLevel(impactLevel)
|
||||||
|
current = this.system.impacts[impactType][impactLevel]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let newImpact = Math.max(this.system.impacts[impactType][impactLevel] + modifier, 0)
|
||||||
|
this.update({ [`system.impacts.${impactType}.${impactLevel}`]: newImpact})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getImpactMalus(impactKey) {
|
||||||
|
let impacts = this.system.impacts[impactKey]
|
||||||
|
return - ((impacts.serious*2) + (impacts.major*4))
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getImpactsMalus() {
|
||||||
|
let impactsMalus = {
|
||||||
|
physical: this.getImpactMalus("physical"),
|
||||||
|
mental: this.getImpactMalus("mental"),
|
||||||
|
social: this.getImpactMalus("social")
|
||||||
|
}
|
||||||
|
return impactsMalus
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
clearInitiative() {
|
||||||
|
this.getFlag("world", "initiative", -1)
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getInitiativeScore(combatId, combatantId) {
|
||||||
|
let init = Math.floor((this.system.attributs.physique.value + this.system.attributs.habilite.value) / 2)
|
||||||
|
let subValue = new Roll("1d20").roll({ async: false })
|
||||||
|
return init + (subValue.total / 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getSubActors() {
|
||||||
|
let subActors = [];
|
||||||
|
for (let id of this.system.subactors) {
|
||||||
|
subActors.push(duplicate(game.actors.get(id)))
|
||||||
|
}
|
||||||
|
return subActors;
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async addSubActor(subActorId) {
|
||||||
|
let subActors = duplicate(this.system.subactors);
|
||||||
|
subActors.push(subActorId);
|
||||||
|
await this.update({ 'system.subactors': subActors });
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async delSubActor(subActorId) {
|
||||||
|
let newArray = [];
|
||||||
|
for (let id of this.system.subactors) {
|
||||||
|
if (id != subActorId) {
|
||||||
|
newArray.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await this.update({ 'system.subactors': newArray });
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async deleteAllItemsByType(itemType) {
|
||||||
|
let items = this.items.filter(item => item.type == itemType);
|
||||||
|
await this.deleteEmbeddedDocuments('Item', items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async addItemWithoutDuplicate(newItem) {
|
||||||
|
let item = this.items.find(item => item.type == newItem.type && item.name.toLowerCase() == newItem.name.toLowerCase())
|
||||||
|
if (!item) {
|
||||||
|
await this.createEmbeddedDocuments('Item', [newItem]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async incDecQuantity(objetId, incDec = 0) {
|
||||||
|
let objetQ = this.items.get(objetId)
|
||||||
|
if (objetQ) {
|
||||||
|
let newQ = objetQ.system.quantity + incDec
|
||||||
|
if (newQ >= 0) {
|
||||||
|
await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantity': newQ }]) // pdates one EmbeddedEntity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
modifyConfrontBonus( modifier ) {
|
||||||
|
let newBonus = this.system.internals.confrontbonus + modifier
|
||||||
|
this.update({'system.internals.confrontbonus': newBonus})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
spentSkillTranscendence(skill, value) {
|
||||||
|
let newValue = this.system.skills[skill.categKey].skilllist[skill.skillKey].value - value
|
||||||
|
newValue = Math.max(0, newValue)
|
||||||
|
this.update({ [`system.skills.${skill.categKey}.skilllist.${skill.skillKey}.value`]: newValue })
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getBonusList() {
|
||||||
|
let bonusList = []
|
||||||
|
for(let i=0; i<this.system.internals.confrontbonus; i++) {
|
||||||
|
bonusList.push( { value: 1, type: "bonus", location: "mainpool"})
|
||||||
|
}
|
||||||
|
return bonusList
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getCommonRollData() {
|
||||||
|
//this.system.internals.confrontbonus = 5 // TO BE REMOVED!!!!
|
||||||
|
let rollData = EcrymeUtility.getBasicRollData()
|
||||||
|
rollData.alias = this.name
|
||||||
|
rollData.actorImg = this.img
|
||||||
|
rollData.actorId = this.id
|
||||||
|
rollData.img = this.img
|
||||||
|
rollData.isReroll = false
|
||||||
|
rollData.traits = duplicate(this.getRollTraits())
|
||||||
|
rollData.spleen = duplicate(this.getSpleen() || {})
|
||||||
|
rollData.ideal = duplicate(this.getIdeal() || {})
|
||||||
|
rollData.confrontBonus = this.getBonusList()
|
||||||
|
|
||||||
|
return rollData
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getCommonSkill(categKey, skillKey) {
|
||||||
|
let skill = this.system.skills[categKey].skilllist[skillKey]
|
||||||
|
let rollData = this.getCommonRollData()
|
||||||
|
|
||||||
|
skill = duplicate(skill)
|
||||||
|
skill.categKey = categKey
|
||||||
|
skill.skillKey = skillKey
|
||||||
|
skill.spec = this.getSpecializations(skillKey)
|
||||||
|
|
||||||
|
rollData.skill = skill
|
||||||
|
rollData.img = skill.img
|
||||||
|
rollData.impactMalus = this.getImpactMalus(categKey)
|
||||||
|
|
||||||
|
return rollData
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
rollSkill(categKey, skillKey) {
|
||||||
|
let rollData = this.getCommonSkill(categKey, skillKey)
|
||||||
|
rollData.mode = "skill"
|
||||||
|
rollData.title = game.i18n.localize(rollData.skill.name)
|
||||||
|
this.startRoll(rollData).catch("Error on startRoll")
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
rollSpec(categKey, skillKey, specId) {
|
||||||
|
let rollData = this.getCommonSkill(categKey, skillKey)
|
||||||
|
let spec = this.items.find(it => it.type == "specialization" && it.id == specId)
|
||||||
|
rollData.mode = "skill"
|
||||||
|
rollData.selectedSpecs = [spec.id]
|
||||||
|
rollData.forcedSpec = duplicate(spec)
|
||||||
|
rollData.title = game.i18n.localize(rollData.skill.name)
|
||||||
|
this.startRoll(rollData).catch("Error on startRoll")
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollSkillConfront(categKey, skillKey) {
|
||||||
|
let rollData = this.getCommonSkill(categKey, skillKey)
|
||||||
|
rollData.mode = "skill"
|
||||||
|
rollData.title = game.i18n.localize("ECRY.ui.confrontation") + " : " + game.i18n.localize(rollData.skill.name)
|
||||||
|
rollData.executionTotal = rollData.skill.value
|
||||||
|
rollData.preservationTotal = rollData.skill.value
|
||||||
|
rollData.applyTranscendence = "execution"
|
||||||
|
rollData.traitsBonus = duplicate(rollData.traits)
|
||||||
|
rollData.traitsMalus = duplicate(rollData.traits)
|
||||||
|
let confrontStartDialog = await EcrymeConfrontStartDialog.create(this, rollData)
|
||||||
|
confrontStartDialog.render(true)
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollCephalySkillConfront(skillKey) {
|
||||||
|
let rollData = this.getCommonRollData()
|
||||||
|
rollData.mode = "cephaly"
|
||||||
|
rollData.skill = duplicate(this.system.cephaly.skilllist[skillKey])
|
||||||
|
rollData.annency = duplicate(this.getAnnency())
|
||||||
|
rollData.img = rollData.skill.img
|
||||||
|
rollData.skill.categKey = "cephaly"
|
||||||
|
rollData.skill.skillKey = skillKey
|
||||||
|
//rollData.impactMalus = this.getImpactMalus(categKey)
|
||||||
|
rollData.title = game.i18n.localize("ECRY.ui.cephaly") + " : " + game.i18n.localize(rollData.skill.name)
|
||||||
|
rollData.executionTotal = rollData.skill.value
|
||||||
|
rollData.preservationTotal = rollData.skill.value
|
||||||
|
rollData.traitsBonus = duplicate(rollData.traits)
|
||||||
|
rollData.traitsMalus = duplicate(rollData.traits)
|
||||||
|
rollData.applyTranscendence = "execution"
|
||||||
|
let confrontStartDialog = await EcrymeConfrontStartDialog.create(this, rollData)
|
||||||
|
confrontStartDialog.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollWeaponConfront(weaponId) {
|
||||||
|
let weapon = this.items.get(weaponId)
|
||||||
|
let rollData
|
||||||
|
if (weapon && weapon.system.weapontype == "melee") {
|
||||||
|
rollData = this.getCommonSkill("physical", "fencing")
|
||||||
|
} else {
|
||||||
|
rollData = this.getCommonSkill("physical", "shooting")
|
||||||
|
}
|
||||||
|
rollData.mode = "weapon"
|
||||||
|
rollData.weapon = duplicate(weapon)
|
||||||
|
rollData.title = game.i18n.localize("ECRY.ui.confrontation") + " : " + game.i18n.localize(rollData.skill.name)
|
||||||
|
rollData.executionTotal = rollData.skill.value
|
||||||
|
rollData.preservationTotal = rollData.skill.value
|
||||||
|
rollData.traitsBonus = duplicate(rollData.traits)
|
||||||
|
rollData.traitsMalus = duplicate(rollData.traits)
|
||||||
|
rollData.applyTranscendence = "execution"
|
||||||
|
let confrontStartDialog = await EcrymeConfrontStartDialog.create(this, rollData)
|
||||||
|
confrontStartDialog.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
rollWeapon(weaponId) {
|
||||||
|
let weapon = this.items.get(weaponId)
|
||||||
|
if (weapon) {
|
||||||
|
weapon = duplicate(weapon)
|
||||||
|
let rollData = this.getCommonRollData()
|
||||||
|
if (weapon.system.armetype == "mainsnues" || weapon.system.armetype == "epee") {
|
||||||
|
rollData.attr = { label: "(Physique+Habilité)/2", value: Math.floor((this.getPhysiqueMalus() + this.system.attributs.physique.value + this.system.attributs.habilite.value) / 2) }
|
||||||
|
} else {
|
||||||
|
rollData.attr = duplicate(this.system.attributs.habilite)
|
||||||
|
}
|
||||||
|
rollData.mode = "weapon"
|
||||||
|
rollData.weapon = weapon
|
||||||
|
rollData.img = weapon.img
|
||||||
|
rollData.title = weapon.name
|
||||||
|
this.startRoll(rollData).catch("Error on startRoll")
|
||||||
|
} else {
|
||||||
|
ui.notifications.warn("Impossible de trouver l'arme concernée ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async startRoll(rollData) {
|
||||||
|
let rollDialog = await EcrymeRollDialog.create(this, rollData)
|
||||||
|
rollDialog.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
modules/app/tedeum-combat.js
Normal file
40
modules/app/tedeum-combat.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { EcrymeUtility } from "../common/tedeum-utility.js";
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
export class EcrymeCombat extends Combat {
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollInitiative(ids, formula = undefined, messageOptions = {} ) {
|
||||||
|
ids = typeof ids === "string" ? [ids] : ids;
|
||||||
|
for (let cId = 0; cId < ids.length; cId++) {
|
||||||
|
const c = this.combatants.get(ids[cId]);
|
||||||
|
let id = c._id || c.id;
|
||||||
|
let initBonus = c.actor ? c.actor.getInitiativeScore( this.id, id ) : -1;
|
||||||
|
await this.updateEmbeddedDocuments("Combatant", [ { _id: id, initiative: initBonus } ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_onUpdate(changed, options, userId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async checkTurnPosition() {
|
||||||
|
while (game.combat.turn > 0) {
|
||||||
|
await game.combat.previousTurn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_onDelete() {
|
||||||
|
let combatants = this.combatants.contents
|
||||||
|
for (let c of combatants) {
|
||||||
|
let actor = game.actors.get(c.actorId)
|
||||||
|
actor.clearInitiative()
|
||||||
|
}
|
||||||
|
super._onDelete()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
105
modules/app/tedeum-commands.js
Normal file
105
modules/app/tedeum-commands.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
import { EcrymeUtility } from "../common/tedeum-utility.js";
|
||||||
|
import { EcrymeCharacterSummary } from "./ecryme-summary-app.js"
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
export class EcrymeCommands {
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
if (!game.system.ecryme.commands) {
|
||||||
|
const commands = new EcrymeCommands();
|
||||||
|
commands.registerCommand({ path: ["/resume"], func: (content, msg, params) => EcrymeCharacterSummary.displayPCSummary(), descr: "Affiche la liste des PJs!" });
|
||||||
|
game.system.ecryme.commands = commands;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constructor() {
|
||||||
|
this.commandsTable = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
registerCommand(command) {
|
||||||
|
this._addCommand(this.commandsTable, command.path, '', command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_addCommand(targetTable, path, fullPath, command) {
|
||||||
|
if (!this._validateCommand(targetTable, path, command)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const term = path[0];
|
||||||
|
fullPath = fullPath + term + ' '
|
||||||
|
if (path.length == 1) {
|
||||||
|
command.descr = `<strong>${fullPath}</strong>: ${command.descr}`;
|
||||||
|
targetTable[term] = command;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!targetTable[term]) {
|
||||||
|
targetTable[term] = { subTable: {} };
|
||||||
|
}
|
||||||
|
this._addCommand(targetTable[term].subTable, path.slice(1), fullPath, command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_validateCommand(targetTable, path, command) {
|
||||||
|
if (path.length > 0 && path[0] && command.descr && (path.length != 1 || targetTable[path[0]] == undefined)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.warn("crucibleCommands._validateCommand failed ", targetTable, path, command);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/* Manage chat commands */
|
||||||
|
processChatCommand(commandLine, content = '', msg = {}) {
|
||||||
|
// Setup new message's visibility
|
||||||
|
let rollMode = game.settings.get("core", "rollMode");
|
||||||
|
if (["gmroll", "blindroll"].includes(rollMode)) msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
|
||||||
|
if (rollMode === "blindroll") msg["blind"] = true;
|
||||||
|
msg["type"] = 0;
|
||||||
|
|
||||||
|
let command = commandLine[0].toLowerCase();
|
||||||
|
let params = commandLine.slice(1);
|
||||||
|
|
||||||
|
return this.process(command, params, content, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
process(command, params, content, msg) {
|
||||||
|
return this._processCommand(this.commandsTable, command, params, content, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
|
||||||
|
console.log("===> Processing command")
|
||||||
|
let command = commandsTable[name];
|
||||||
|
path = path + name + " ";
|
||||||
|
if (command && command.subTable) {
|
||||||
|
if (params[0]) {
|
||||||
|
return this._processCommand(command.subTable, params[0], params.slice(1), content, msg, path)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.help(msg, command.subTable);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (command && command.func) {
|
||||||
|
const result = command.func(content, msg, params);
|
||||||
|
if (result == false) {
|
||||||
|
CrucibleCommands._chatAnswer(msg, command.descr);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _chatAnswer(msg, content) {
|
||||||
|
msg.whisper = [game.user.id];
|
||||||
|
msg.content = content;
|
||||||
|
ChatMessage.create(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
86
modules/app/tedeum-hotbar.js
Normal file
86
modules/app/tedeum-hotbar.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
export class EcrymeHotbar {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a macro when dropping an entity on the hotbar
|
||||||
|
* Item - open roll dialog for item
|
||||||
|
* Actor - open actor sheet
|
||||||
|
* Journal - open journal sheet
|
||||||
|
*/
|
||||||
|
static init( ) {
|
||||||
|
|
||||||
|
Hooks.on("hotbarDrop", async (bar, documentData, slot) => {
|
||||||
|
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill
|
||||||
|
if (documentData.type == "Item") {
|
||||||
|
console.log("Drop done !!!", bar, documentData, slot)
|
||||||
|
let item = documentData.data
|
||||||
|
let command = `game.system.ecryme.EcrymeHotbar.rollMacro("${item.name}", "${item.type}");`
|
||||||
|
let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command))
|
||||||
|
if (!macro) {
|
||||||
|
macro = await Macro.create({
|
||||||
|
name: item.name,
|
||||||
|
type: "script",
|
||||||
|
img: item.img,
|
||||||
|
command: command
|
||||||
|
}, { displaySheet: false })
|
||||||
|
}
|
||||||
|
game.user.assignHotbarMacro(macro, slot);
|
||||||
|
}
|
||||||
|
// Create a macro to open the actor sheet of the actor dropped on the hotbar
|
||||||
|
else if (documentData.type == "Actor") {
|
||||||
|
let actor = game.actors.get(documentData.id);
|
||||||
|
let command = `game.actors.get("${documentData.id}").sheet.render(true)`
|
||||||
|
let macro = game.macros.contents.find(m => (m.name === actor.name) && (m.command === command));
|
||||||
|
if (!macro) {
|
||||||
|
macro = await Macro.create({
|
||||||
|
name: actor.data.name,
|
||||||
|
type: "script",
|
||||||
|
img: actor.data.img,
|
||||||
|
command: command
|
||||||
|
}, { displaySheet: false })
|
||||||
|
game.user.assignHotbarMacro(macro, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Create a macro to open the journal sheet of the journal dropped on the hotbar
|
||||||
|
else if (documentData.type == "JournalEntry") {
|
||||||
|
let journal = game.journal.get(documentData.id);
|
||||||
|
let command = `game.journal.get("${documentData.id}").sheet.render(true)`
|
||||||
|
let macro = game.macros.contents.find(m => (m.name === journal.name) && (m.command === command));
|
||||||
|
if (!macro) {
|
||||||
|
macro = await Macro.create({
|
||||||
|
name: journal.data.name,
|
||||||
|
type: "script",
|
||||||
|
img: "",
|
||||||
|
command: command
|
||||||
|
}, { displaySheet: false })
|
||||||
|
game.user.assignHotbarMacro(macro, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Roll macro */
|
||||||
|
static rollMacro(itemName, itemType, bypassData) {
|
||||||
|
const speaker = ChatMessage.getSpeaker()
|
||||||
|
let actor
|
||||||
|
if (speaker.token) actor = game.actors.tokens[speaker.token]
|
||||||
|
if (!actor) actor = game.actors.get(speaker.actor)
|
||||||
|
if (!actor) {
|
||||||
|
return ui.notifications.warn(`Select your actor to run the macro`)
|
||||||
|
}
|
||||||
|
|
||||||
|
let item = actor.items.find(it => it.name === itemName && it.type == itemType)
|
||||||
|
if (!item ) {
|
||||||
|
return ui.notifications.warn(`Unable to find the item of the macro in the current actor`)
|
||||||
|
}
|
||||||
|
// Trigger the item roll
|
||||||
|
if (item.type === "weapon") {
|
||||||
|
return actor.rollWeapon( item.id)
|
||||||
|
}
|
||||||
|
if (item.type === "skill") {
|
||||||
|
return actor.rollSkill( item.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
62
modules/common/tedeum-config.js
Normal file
62
modules/common/tedeum-config.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
export const ECRYME_CONFIG = {
|
||||||
|
|
||||||
|
traitTypes: {
|
||||||
|
normal: "Normal",
|
||||||
|
spleen: "Spleen",
|
||||||
|
ideal: "Ideal"
|
||||||
|
},
|
||||||
|
weaponTypes: {
|
||||||
|
"melee": "ECRY.ui.melee",
|
||||||
|
"ranged": "ECRY.ui.ranged"
|
||||||
|
},
|
||||||
|
traitLevel: [
|
||||||
|
{value: -3, text: "-3"},
|
||||||
|
{value: -2, text: "-2"},
|
||||||
|
{value: -1, text: "-1"},
|
||||||
|
{value: +1, text: "+1"},
|
||||||
|
{value: +2, text: "+2"},
|
||||||
|
{value: +3, text: "+3"}
|
||||||
|
],
|
||||||
|
impactTypes: {
|
||||||
|
physical: "ECRY.ui.physical",
|
||||||
|
mental: "ECRY.ui.mental",
|
||||||
|
social: "ECRY.ui.social"
|
||||||
|
},
|
||||||
|
impactLevels: {
|
||||||
|
superficial: "ECRY.ui.superficial",
|
||||||
|
light: "ECRY.ui.light",
|
||||||
|
serious: "ECRY.ui.serious",
|
||||||
|
major: "ECRY.ui.major"
|
||||||
|
},
|
||||||
|
difficulty: {
|
||||||
|
"-1": {difficulty: "ECRY.ui.none", frequency: "ECRY.ui.none", value: "-"},
|
||||||
|
"8": { difficulty: "ECRY.ui.troublesome", frequency: "ECRY.ui.occasional", value: 8 },
|
||||||
|
"10": { difficulty: "ECRY.ui.difficult", frequency: "ECRY.ui.uncommon", value: 10 },
|
||||||
|
"12": { difficulty: "ECRY.ui.verydifficult", frequency: "ECRY.ui.rare", value: 12 },
|
||||||
|
"14": { difficulty: "ECRY.ui.extremdifficult", frequency: "ECRY.ui.veryrare", value: 14 },
|
||||||
|
"16": { difficulty: "ECRY.ui.increddifficult", frequency: "ECRY.ui.exceptrare", value: 16 },
|
||||||
|
},
|
||||||
|
skillLevel: {
|
||||||
|
"0": "0",
|
||||||
|
"1": "1",
|
||||||
|
"2": "2",
|
||||||
|
"3": "3",
|
||||||
|
"4": "4",
|
||||||
|
"5": "5",
|
||||||
|
"6": "6",
|
||||||
|
"7": "7",
|
||||||
|
"8": "8",
|
||||||
|
"9": "9",
|
||||||
|
"10": "10"
|
||||||
|
},
|
||||||
|
costUnits: {
|
||||||
|
"ingot": {name: "ECRY.ui.ingot", value: 100000},
|
||||||
|
"ingotin": {name: "ECRY.ui.ingotin", value: 10000},
|
||||||
|
"goldcoin": {name: "ECRY.ui.goldcoin", value: 1000 },
|
||||||
|
"lige": {name: "ECRY.ui.lige", value: 100 },
|
||||||
|
"hurle": {name: "ECRY.ui.hurle", value: 10 },
|
||||||
|
"coin": {name: "ECRY.ui.coin", value: 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
745
modules/common/tedeum-utility.js
Normal file
745
modules/common/tedeum-utility.js
Normal file
@ -0,0 +1,745 @@
|
|||||||
|
/* -------------------------------------------- */
|
||||||
|
import { EcrymeCommands } from "../app/tedeum-commands.js";
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
const __maxImpacts = { superficial: 4, light: 3, serious: 2, major: 1 }
|
||||||
|
const __nextImpacts = { superficial: "light", light: "serious", serious: "major", major: "major" }
|
||||||
|
const __effect2Impact = ["none", "superficial", "superficial", "light", "light", "serious", "serious", "major", "major"]
|
||||||
|
const __cephalySuccess = {
|
||||||
|
1: "cephaly-success-2",
|
||||||
|
2: "cephaly-success-2",
|
||||||
|
3: "cephaly-success-4",
|
||||||
|
4: "cephaly-success-4",
|
||||||
|
5: "cephaly-success-6",
|
||||||
|
6: "cephaly-success-6",
|
||||||
|
7: "cephaly-success-8",
|
||||||
|
8: "cephaly-success-8",
|
||||||
|
9: "cephaly-success-9",
|
||||||
|
10: "cephaly-success-10"
|
||||||
|
}
|
||||||
|
const __cephalyFailure = {
|
||||||
|
1: "cephaly-failure-2",
|
||||||
|
2: "cephaly-failure-2",
|
||||||
|
3: "cephaly-failure-4",
|
||||||
|
4: "cephaly-failure-4",
|
||||||
|
5: "cephaly-failure-6",
|
||||||
|
6: "cephaly-failure-6",
|
||||||
|
7: "cephaly-failure-8",
|
||||||
|
8: "cephaly-failure-8",
|
||||||
|
9: "cephaly-failure-9",
|
||||||
|
10: "cephaly-failure-10"
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
export class EcrymeUtility {
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async init() {
|
||||||
|
Hooks.on('renderChatLog', (log, html, data) => EcrymeUtility.chatListeners(html));
|
||||||
|
Hooks.on("getChatLogEntryContext", (html, options) => EcrymeUtility.chatMenuManager(html, options));
|
||||||
|
|
||||||
|
this.rollDataStore = {}
|
||||||
|
this.defenderStore = {}
|
||||||
|
|
||||||
|
EcrymeCommands.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async ready() {
|
||||||
|
|
||||||
|
Handlebars.registerHelper('count', function (list) {
|
||||||
|
return list.length;
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('includes', function (array, val) {
|
||||||
|
return array.includes(val);
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('upper', function (text) {
|
||||||
|
return text.toUpperCase();
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('lower', function (text) {
|
||||||
|
return text.toLowerCase()
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('upperFirst', function (text) {
|
||||||
|
if (typeof text !== 'string') return text
|
||||||
|
return text.charAt(0).toUpperCase() + text.slice(1)
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('notEmpty', function (list) {
|
||||||
|
return list.length > 0;
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('mul', function (a, b) {
|
||||||
|
return parseInt(a) * parseInt(b);
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('add', function (a, b) {
|
||||||
|
return parseInt(a) + parseInt(b);
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('valueAtIndex', function (arr, idx) {
|
||||||
|
return arr[idx];
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('for', function (from, to, incr, block) {
|
||||||
|
let accum = '';
|
||||||
|
for (let i = from; i <= to; i += incr)
|
||||||
|
accum += block.fn(i);
|
||||||
|
return accum;
|
||||||
|
})
|
||||||
|
Handlebars.registerHelper('isGM', function () {
|
||||||
|
return game.user.isGM
|
||||||
|
})
|
||||||
|
|
||||||
|
game.settings.register("fvtt-ecryme", "ecryme-game-level", {
|
||||||
|
name: game.i18n.localize("ECRY.settings.gamelevel"),
|
||||||
|
label: game.i18n.localize("ECRY.settings.gamelevelhelp"),
|
||||||
|
scope: 'world',
|
||||||
|
config: true,
|
||||||
|
type: String,
|
||||||
|
choices: {
|
||||||
|
"level_e": game.i18n.localize("ECRY.settings.cogs"),
|
||||||
|
"level_c": game.i18n.localize("ECRY.settings.cephaly"),
|
||||||
|
"level_b": game.i18n.localize("ECRY.settings.boheme"),
|
||||||
|
"level_a": game.i18n.localize("ECRY.settings.amertume"),
|
||||||
|
},
|
||||||
|
restricted: true
|
||||||
|
})
|
||||||
|
|
||||||
|
this.buildSkillConfig()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------- */
|
||||||
|
static hasCephaly() {
|
||||||
|
let level = game.settings.get("fvtt-ecryme", "ecryme-game-level")
|
||||||
|
return level != "level_e"
|
||||||
|
}
|
||||||
|
/*-------------------------------------------- */
|
||||||
|
static hasBoheme() {
|
||||||
|
let level = game.settings.get("fvtt-ecryme", "ecryme-game-level")
|
||||||
|
return level == "level_b" || level == "level_a"
|
||||||
|
}
|
||||||
|
/*-------------------------------------------- */
|
||||||
|
static hasAmertume() {
|
||||||
|
let level = game.settings.get("fvtt-ecryme", "ecryme-game-level")
|
||||||
|
return level == "level_a"
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------- */
|
||||||
|
static buildSkillConfig() {
|
||||||
|
game.system.ecryme.config.skills = {}
|
||||||
|
for (let categKey in game.data.template.Actor.templates.core.skills) {
|
||||||
|
let category = game.data.template.Actor.templates.core.skills[categKey]
|
||||||
|
for (let skillKey in category.skilllist) {
|
||||||
|
let skill = duplicate(category.skilllist[skillKey])
|
||||||
|
skill.categKey = categKey // Auto reference the category
|
||||||
|
game.system.ecryme.config.skills[skillKey] = skill
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------- */
|
||||||
|
static upperFirst(text) {
|
||||||
|
if (typeof text !== 'string') return text
|
||||||
|
return text.charAt(0).toUpperCase() + text.slice(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async loadCompendiumData(compendium) {
|
||||||
|
const pack = game.packs.get(compendium)
|
||||||
|
return await pack?.getDocuments() ?? []
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async loadCompendium(compendium, filter = item => true) {
|
||||||
|
let compendiumData = await EcrymeUtility.loadCompendiumData(compendium)
|
||||||
|
return compendiumData.filter(filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getActorFromRollData(rollData) {
|
||||||
|
let actor = game.actors.get(rollData.actorId)
|
||||||
|
if (rollData.tokenId) {
|
||||||
|
let token = canvas.tokens.placeables.find(t => t.id == rollData.tokenId)
|
||||||
|
if (token) {
|
||||||
|
actor = token.actor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actor
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getImpactFromEffect(effectValue) {
|
||||||
|
if (effectValue >= __effect2Impact.length) {
|
||||||
|
return "major"
|
||||||
|
}
|
||||||
|
return __effect2Impact[effectValue]
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async processConfrontation() {
|
||||||
|
let confront = {
|
||||||
|
type: "confront-data",
|
||||||
|
rollData1: this.confrontData1,
|
||||||
|
rollData2: this.confrontData2,
|
||||||
|
}
|
||||||
|
// Compute margin
|
||||||
|
confront.marginExecution = this.confrontData1.executionTotal - this.confrontData2.preservationTotal
|
||||||
|
confront.marginPreservation = this.confrontData1.preservationTotal - this.confrontData2.executionTotal
|
||||||
|
console.log(confront.marginExecution, confront.marginPreservation)
|
||||||
|
// Filter margin
|
||||||
|
let maxMargin // Dummy max
|
||||||
|
if (confront.marginExecution > 0) { // Successful hit
|
||||||
|
// Limit with skill+spec
|
||||||
|
maxMargin = confront.rollData1.skill.value + ((confront.rollData1.spec) ? 2 : 0)
|
||||||
|
confront.marginExecution = Math.min(confront.marginExecution, maxMargin)
|
||||||
|
} else { // Failed hit
|
||||||
|
maxMargin = confront.rollData2.skill.value + ((confront.rollData2.spec) ? 2 : 0)
|
||||||
|
confront.marginExecution = -Math.min(Math.abs(confront.marginExecution), maxMargin)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confront.marginPreservation > 0) { // Successful defense
|
||||||
|
// Limit with skill+spec
|
||||||
|
maxMargin = confront.rollData1.skill.value + ((confront.rollData1.spec) ? 2 : 0)
|
||||||
|
confront.marginPreservation = Math.min(confront.marginPreservation, maxMargin)
|
||||||
|
} else { // Failed defense
|
||||||
|
maxMargin = confront.rollData2.skill.value + ((confront.rollData2.spec) ? 2 : 0)
|
||||||
|
confront.marginPreservation = - Math.min(Math.abs(confront.marginPreservation), maxMargin)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute effects
|
||||||
|
confront.effectExecution = confront.marginExecution
|
||||||
|
if (confront.rollData1.weapon && confront.marginExecution > 0) {
|
||||||
|
confront.effectExecution += confront.rollData1.weapon.system.effect
|
||||||
|
confront.impactExecution = this.getImpactFromEffect(confront.effectExecution)
|
||||||
|
}
|
||||||
|
if (confront.marginExecution < 0) {
|
||||||
|
confront.bonus2 = -confront.marginExecution
|
||||||
|
}
|
||||||
|
confront.effectPreservation = confront.marginPreservation
|
||||||
|
if (confront.rollData2.weapon && confront.marginPreservation < 0) {
|
||||||
|
confront.effectPreservation = - (Math.abs(confront.marginPreservation) + confront.rollData2.weapon.system.effect)
|
||||||
|
confront.impactPreservation = this.getImpactFromEffect(Math.abs(confront.effectPreservation))
|
||||||
|
}
|
||||||
|
if (confront.marginPreservation > 0) {
|
||||||
|
confront.bonus1 = -confront.marginPreservation
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = await this.createChatWithRollMode(this.confrontData1.alias, {
|
||||||
|
content: await renderTemplate(`systems/fvtt-ecryme/templates/chat/chat-confrontation-result.hbs`, confront)
|
||||||
|
})
|
||||||
|
await msg.setFlag("world", "ecryme-rolldata", confront)
|
||||||
|
console.log("Confront result", confront)
|
||||||
|
|
||||||
|
this.lastConfront = confront
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async manageCephalyDifficulty(rollData, difficulty) {
|
||||||
|
rollData.difficulty = Number(difficulty)
|
||||||
|
if (rollData.executionTotal > difficulty) {
|
||||||
|
rollData.marginExecution = rollData.executionTotal - difficulty
|
||||||
|
rollData.cephalySuccess = "ECRY.rule." + __cephalySuccess[(rollData.marginExecution > 10) ? 10 : rollData.marginExecution]
|
||||||
|
} else {
|
||||||
|
rollData.marginExecution = -1
|
||||||
|
}
|
||||||
|
if (rollData.preservationTotal < difficulty) {
|
||||||
|
rollData.marginPreservation = difficulty - rollData.preservationTotal
|
||||||
|
rollData.cephalyFailure = "ECRY.rule." + __cephalyFailure[(rollData.marginPreservation > 10) ? 10 : rollData.marginPreservation]
|
||||||
|
} else {
|
||||||
|
rollData.marginPreservation = -1
|
||||||
|
}
|
||||||
|
let msg = await this.createChatWithRollMode(rollData.alias, {
|
||||||
|
content: await renderTemplate(`systems/fvtt-ecryme/templates/chat/chat-cephaly-result.hbs`, rollData)
|
||||||
|
})
|
||||||
|
msg.setFlag("world", "ecryme-rolldata", rollData)
|
||||||
|
console.log("Cephaly result", rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static manageConfrontation(rollData) {
|
||||||
|
console.log("Confront", rollData)
|
||||||
|
// Auto - Reset
|
||||||
|
if (this.confrontData1 && this.confrontData2) {
|
||||||
|
this.confrontData1 = undefined
|
||||||
|
this.confrontData2 = undefined
|
||||||
|
}
|
||||||
|
// Then attribute
|
||||||
|
if (!this.confrontData1) {
|
||||||
|
this.confrontData1 = rollData
|
||||||
|
} else if (this.confrontData1 && this.confrontData1.rollId != rollData.rollId) {
|
||||||
|
this.confrontData2 = rollData
|
||||||
|
this.processConfrontation().catch("Error during confrontation processing")
|
||||||
|
} else {
|
||||||
|
ui.notifications.warn(game.i18n.localize("ECRY.warn.confrontalready"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static chatMenuManager(html, options) {
|
||||||
|
let canTranscendRoll = []
|
||||||
|
for (let i = 1; i <= 10; i++) {
|
||||||
|
canTranscendRoll[i] = function (li) {
|
||||||
|
let message = game.messages.get(li.attr("data-message-id"))
|
||||||
|
let rollData = message.getFlag("world", "rolldata")
|
||||||
|
//console.log(">>>>>>>>>>>>>>>>>>>>>>>>>> Menu !!!!", rollData)
|
||||||
|
if (rollData.skill && i <= rollData.skill.value && !rollData.transcendUsed && rollData.spec) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
options.push({
|
||||||
|
name: game.i18n.localize("ECRY.chat.spectranscend") + i,
|
||||||
|
icon: '<i class="fas fa-plus-square"></i>',
|
||||||
|
condition: canTranscendRoll[i],
|
||||||
|
callback: li => {
|
||||||
|
let message = game.messages.get(li.attr("data-message-id"))
|
||||||
|
let rollData = message.getFlag("world", "rolldata")
|
||||||
|
EcrymeUtility.transcendFromSpec(rollData, i).catch("Error on Transcend")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async chatListeners(html) {
|
||||||
|
|
||||||
|
html.on("click", '.button-select-confront', event => {
|
||||||
|
let messageId = EcrymeUtility.findChatMessageId(event.currentTarget)
|
||||||
|
let message = game.messages.get(messageId)
|
||||||
|
let rollData = message.getFlag("world", "ecryme-rolldata")
|
||||||
|
ui.notifications.info( game.i18n.localize("ECRY.chat.confrontselect"))
|
||||||
|
EcrymeUtility.manageConfrontation(rollData)
|
||||||
|
})
|
||||||
|
html.on("click", '.button-apply-cephaly-difficulty', event => {
|
||||||
|
let messageId = EcrymeUtility.findChatMessageId(event.currentTarget)
|
||||||
|
let message = game.messages.get(messageId)
|
||||||
|
let rollData = message.getFlag("world", "ecryme-rolldata")
|
||||||
|
let difficulty = $("#" + rollData.rollId + "-cephaly-difficulty").val()
|
||||||
|
EcrymeUtility.manageCephalyDifficulty(rollData, difficulty)
|
||||||
|
})
|
||||||
|
html.on("click", '.button-apply-impact', event => {
|
||||||
|
let messageId = EcrymeUtility.findChatMessageId(event.currentTarget)
|
||||||
|
let message = game.messages.get(messageId)
|
||||||
|
let actor = game.actors.get($(event.currentTarget).data("actor-id"))
|
||||||
|
actor.modifyImpact($(event.currentTarget).data("impact-type"), $(event.currentTarget).data("impact"), 1)
|
||||||
|
})
|
||||||
|
html.on("click", '.button-apply-bonus', event => {
|
||||||
|
let messageId = EcrymeUtility.findChatMessageId(event.currentTarget)
|
||||||
|
let message = game.messages.get(messageId)
|
||||||
|
let actor = game.actors.get($(event.currentTarget).data("actor-id"))
|
||||||
|
actor.modifyConfrontBonus($(event.currentTarget).data("bonus"))
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async preloadHandlebarsTemplates() {
|
||||||
|
|
||||||
|
const templatePaths = [
|
||||||
|
'systems/fvtt-ecryme/templates/actors/editor-notes-gm.hbs',
|
||||||
|
'systems/fvtt-ecryme/templates/items/partial-item-nav.hbs',
|
||||||
|
'systems/fvtt-ecryme/templates/items/partial-item-equipment.hbs',
|
||||||
|
'systems/fvtt-ecryme/templates/items/partial-item-description.hbs',
|
||||||
|
'systems/fvtt-ecryme/templates/dialogs/partial-common-roll-dialog.hbs',
|
||||||
|
'systems/fvtt-ecryme/templates/dialogs/partial-confront-dice-area.hbs',
|
||||||
|
'systems/fvtt-ecryme/templates/dialogs/partial-confront-bonus-area.hbs',
|
||||||
|
'systems/fvtt-ecryme/templates/actors/partial-impacts.hbs',
|
||||||
|
]
|
||||||
|
return loadTemplates(templatePaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static removeChatMessageId(messageId) {
|
||||||
|
if (messageId) {
|
||||||
|
game.messages.get(messageId)?.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static findChatMessageId(current) {
|
||||||
|
return EcrymeUtility.getChatMessageId(EcrymeUtility.findChatMessage(current));
|
||||||
|
}
|
||||||
|
|
||||||
|
static getChatMessageId(node) {
|
||||||
|
return node?.attributes.getNamedItem('data-message-id')?.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static findChatMessage(current) {
|
||||||
|
return EcrymeUtility.findNodeMatching(current, it => it.classList.contains('chat-message') && it.attributes.getNamedItem('data-message-id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static findNodeMatching(current, predicate) {
|
||||||
|
if (current) {
|
||||||
|
if (predicate(current)) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
return EcrymeUtility.findNodeMatching(current.parentElement, predicate);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static createDirectOptionList(min, max) {
|
||||||
|
let options = {};
|
||||||
|
for (let i = min; i <= max; i++) {
|
||||||
|
options[`${i}`] = `${i}`;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static buildListOptions(min, max) {
|
||||||
|
let options = ""
|
||||||
|
for (let i = min; i <= max; i++) {
|
||||||
|
options += `<option value="${i}">${i}</option>`
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getTarget() {
|
||||||
|
if (game.user.targets) {
|
||||||
|
for (let target of game.user.targets) {
|
||||||
|
return target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static updateRollData(rollData) {
|
||||||
|
|
||||||
|
let id = rollData.rollId
|
||||||
|
let oldRollData = this.rollDataStore[id] || {}
|
||||||
|
let newRollData = mergeObject(oldRollData, rollData)
|
||||||
|
this.rollDataStore[id] = newRollData
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async onSocketMesssage(msg) {
|
||||||
|
console.log("SOCKET MESSAGE", msg)
|
||||||
|
if (msg.name == "msg_gm_chat_message") {
|
||||||
|
let rollData = msg.data.rollData
|
||||||
|
if ( game.user.isGM ) {
|
||||||
|
let chatMsg = await this.createChatMessage(rollData.alias, "blindroll", {
|
||||||
|
content: await renderTemplate(msg.data.template, rollData),
|
||||||
|
whisper: game.user.id
|
||||||
|
})
|
||||||
|
chatMsg.setFlag("world", "ecryme-rolldata", rollData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async searchItem(dataItem) {
|
||||||
|
let item
|
||||||
|
if (dataItem.pack) {
|
||||||
|
let id = dataItem.id || dataItem._id
|
||||||
|
let items = await this.loadCompendium(dataItem.pack, item => item.id == id)
|
||||||
|
item = items[0] || undefined
|
||||||
|
} else {
|
||||||
|
item = game.items.get(dataItem.id)
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static chatDataSetup(content, modeOverride, forceWhisper, isRoll = false) {
|
||||||
|
let chatData = {
|
||||||
|
user: game.user.id,
|
||||||
|
rollMode: modeOverride || game.settings.get("core", "rollMode"),
|
||||||
|
content: content
|
||||||
|
};
|
||||||
|
|
||||||
|
if (["gmroll", "blindroll"].includes(chatData.rollMode)) chatData["whisper"] = ChatMessage.getWhisperRecipients("GM").map(u => u.id);
|
||||||
|
if (chatData.rollMode === "blindroll") chatData["blind"] = true;
|
||||||
|
else if (chatData.rollMode === "selfroll") chatData["whisper"] = [game.user];
|
||||||
|
|
||||||
|
if (forceWhisper) { // Final force !
|
||||||
|
chatData["speaker"] = ChatMessage.getSpeaker();
|
||||||
|
chatData["whisper"] = ChatMessage.getWhisperRecipients(forceWhisper);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chatData;
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getImpactMax(impactLevel) {
|
||||||
|
return __maxImpacts[impactLevel]
|
||||||
|
}
|
||||||
|
static getNextImpactLevel(impactLevel) {
|
||||||
|
return __nextImpacts[impactLevel]
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async showDiceSoNice(roll, rollMode) {
|
||||||
|
if (game.modules.get("dice-so-nice")?.active) {
|
||||||
|
if (game.dice3d) {
|
||||||
|
let whisper = null;
|
||||||
|
let blind = false;
|
||||||
|
rollMode = rollMode ?? game.settings.get("core", "rollMode");
|
||||||
|
switch (rollMode) {
|
||||||
|
case "blindroll": //GM only
|
||||||
|
whisper = this.getUsers(user => user.isGM);
|
||||||
|
blind = true;
|
||||||
|
break
|
||||||
|
case "gmroll": //GM + rolling player
|
||||||
|
whisper = this.getUsers(user => user.isGM);
|
||||||
|
break;
|
||||||
|
case "roll": //everybody
|
||||||
|
whisper = this.getUsers(user => user.active);
|
||||||
|
break;
|
||||||
|
case "selfroll":
|
||||||
|
whisper = [game.user.id];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static computeResults(rollData) {
|
||||||
|
rollData.isSuccess = false
|
||||||
|
if (!rollData.difficulty || rollData.difficulty == "-") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rollData.margin = rollData.total - rollData.difficulty
|
||||||
|
if (rollData.total > rollData.difficulty) {
|
||||||
|
rollData.isSuccess = true
|
||||||
|
let maxMargin = rollData.skill.value + ((rollData.spec) ? 2 : 0)
|
||||||
|
rollData.margin = Math.min(rollData.margin, maxMargin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static computeRollFormula(rollData, actor, isConfrontation = false) {
|
||||||
|
// Build the dice formula
|
||||||
|
let diceFormula = (isConfrontation) ? "4d6" : "2d6"
|
||||||
|
if (rollData.useIdeal) {
|
||||||
|
diceFormula = (isConfrontation) ? "5d6kh2" : "3d6kh2"
|
||||||
|
}
|
||||||
|
if (rollData.useSpleen) {
|
||||||
|
diceFormula = (isConfrontation) ? "5d6kl2" : "3d6kl2"
|
||||||
|
}
|
||||||
|
if (rollData.skill) {
|
||||||
|
diceFormula += "+" + rollData.skill.value
|
||||||
|
}
|
||||||
|
if (rollData.skillTranscendence) {
|
||||||
|
diceFormula += "+" + rollData.skillTranscendence
|
||||||
|
actor.spentSkillTranscendence(rollData.skill, rollData.skillTranscendence)
|
||||||
|
}
|
||||||
|
if (rollData.selectedSpecs && rollData.selectedSpecs.length > 0) {
|
||||||
|
rollData.spec = actor.getSpecialization(rollData.selectedSpecs[0])
|
||||||
|
diceFormula += "+" + (String(rollData.spec.system?.bonus) || "2")
|
||||||
|
}
|
||||||
|
rollData.bonusMalusTraits = 0
|
||||||
|
if (rollData.traitsBonus && rollData.traitsBonus.length > 0) {
|
||||||
|
rollData.traitsBonusList = []
|
||||||
|
for (let id of rollData.traitsBonus) {
|
||||||
|
let trait = actor.getTrait(id)
|
||||||
|
console.log(trait, id)
|
||||||
|
rollData.traitsBonusList.push(trait)
|
||||||
|
rollData.bonusMalusTraits += trait.system.level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rollData.traitsMalus && rollData.traitsMalus.length > 0) {
|
||||||
|
rollData.traitsMalusList = []
|
||||||
|
for (let id of rollData.traitsMalus) {
|
||||||
|
let trait = actor.getTrait(id)
|
||||||
|
rollData.traitsMalusList.push(trait)
|
||||||
|
rollData.bonusMalusTraits -= trait.system.level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diceFormula += "+" + rollData.bonusMalusTraits
|
||||||
|
diceFormula += "+" + rollData.bonusMalusPerso
|
||||||
|
diceFormula += "+" + rollData.impactMalus
|
||||||
|
if (rollData.annency) {
|
||||||
|
diceFormula += "+" + rollData.annencyBonus
|
||||||
|
}
|
||||||
|
rollData.diceFormula = diceFormula
|
||||||
|
return diceFormula
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async rollEcryme(rollData) {
|
||||||
|
|
||||||
|
let actor = game.actors.get(rollData.actorId)
|
||||||
|
// Fix difficulty
|
||||||
|
if (!rollData.difficulty || rollData.difficulty == "-") {
|
||||||
|
rollData.difficulty = 0
|
||||||
|
}
|
||||||
|
rollData.difficulty = Number(rollData.difficulty)
|
||||||
|
|
||||||
|
let diceFormula = this.computeRollFormula(rollData, actor)
|
||||||
|
|
||||||
|
// Performs roll
|
||||||
|
let myRoll = new Roll(diceFormula).roll({ async: false })
|
||||||
|
await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode"))
|
||||||
|
rollData.roll = duplicate(myRoll)
|
||||||
|
rollData.total = myRoll.total
|
||||||
|
rollData.diceSum = myRoll.terms[0].total
|
||||||
|
|
||||||
|
this.computeResults(rollData)
|
||||||
|
|
||||||
|
let msg = await this.createChatWithRollMode(rollData.alias, {
|
||||||
|
content: await renderTemplate(`systems/fvtt-ecryme/templates/chat/chat-generic-result.hbs`, rollData)
|
||||||
|
})
|
||||||
|
await msg.setFlag("world", "ecryme-rolldata", rollData)
|
||||||
|
console.log("Rolldata result", rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async transcendFromSpec(rollData, value) {
|
||||||
|
rollData.total += value
|
||||||
|
rollData.transcendUsed = true
|
||||||
|
this.computeResults(rollData)
|
||||||
|
//console.log("Adding spec", value, rollData.total)
|
||||||
|
|
||||||
|
let actor = game.actors.get(rollData.actorId)
|
||||||
|
actor.spentSkillTranscendence(rollData.skill, value)
|
||||||
|
|
||||||
|
let msg = await this.createChatWithRollMode(rollData.alias, {
|
||||||
|
content: await renderTemplate(`systems/fvtt-ecryme/templates/chat/chat-generic-result.hbs`, rollData)
|
||||||
|
})
|
||||||
|
await msg.setFlag("world", "ecryme-rolldata", rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static sortArrayObjectsByName(myArray) {
|
||||||
|
myArray.sort((a, b) => {
|
||||||
|
let fa = a.name.toLowerCase();
|
||||||
|
let fb = b.name.toLowerCase();
|
||||||
|
if (fa < fb) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (fa > fb) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getUsers(filter) {
|
||||||
|
return game.users.filter(filter).map(user => user.id);
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getWhisperRecipients(rollMode, name) {
|
||||||
|
switch (rollMode) {
|
||||||
|
case "blindroll": return this.getUsers(user => user.isGM);
|
||||||
|
case "gmroll": return this.getWhisperRecipientsAndGMs(name);
|
||||||
|
case "useronly": return this.getWhisperRecipientsOnly(name);
|
||||||
|
case "selfroll": return [game.user.id];
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getWhisperRecipientsOnly(name) {
|
||||||
|
let recep1 = ChatMessage.getWhisperRecipients(name) || [];
|
||||||
|
return recep1
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getWhisperRecipientsAndGMs(name) {
|
||||||
|
let recep1 = ChatMessage.getWhisperRecipients(name) || [];
|
||||||
|
return recep1.concat(ChatMessage.getWhisperRecipients('GM'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static blindMessageToGM(chatData) {
|
||||||
|
chatData.whisper = this.getUsers(user => user.isGM);
|
||||||
|
console.log("blindMessageToGM", chatData);
|
||||||
|
game.socket.emit("system.fvtt-ecryme", { name: "msg_gm_chat_message", data: chatData });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static split3Columns(data) {
|
||||||
|
|
||||||
|
let array = [[], [], []];
|
||||||
|
if (data == undefined) return array;
|
||||||
|
|
||||||
|
let col = 0;
|
||||||
|
for (let key in data) {
|
||||||
|
let keyword = data[key];
|
||||||
|
keyword.key = key; // Self-reference
|
||||||
|
array[col].push(keyword);
|
||||||
|
col++;
|
||||||
|
if (col == 3) col = 0;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async createChatMessage(name, rollMode, chatOptions) {
|
||||||
|
switch (rollMode) {
|
||||||
|
case "blindroll": // GM only
|
||||||
|
if (!game.user.isGM) {
|
||||||
|
chatOptions.whisper = [game.user.id];
|
||||||
|
} else {
|
||||||
|
chatOptions.whisper = this.getUsers(user => user.isGM);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
chatOptions.whisper = this.getWhisperRecipients(rollMode, name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
chatOptions.alias = chatOptions.alias || name;
|
||||||
|
return await ChatMessage.create(chatOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getBasicRollData() {
|
||||||
|
let rollData = {
|
||||||
|
rollId: randomID(16),
|
||||||
|
type: "roll-data",
|
||||||
|
bonusMalusPerso: 0,
|
||||||
|
bonusMalusSituation: 0,
|
||||||
|
bonusMalusDef: 0,
|
||||||
|
annencyBonus: 0,
|
||||||
|
bonusMalusPortee: 0,
|
||||||
|
skillTranscendence: 0,
|
||||||
|
rollMode: game.settings.get("core", "rollMode"),
|
||||||
|
difficulty: "-",
|
||||||
|
useSpleen: false,
|
||||||
|
useIdeal: false,
|
||||||
|
impactMalus: 0,
|
||||||
|
config: duplicate(game.system.ecryme.config)
|
||||||
|
}
|
||||||
|
EcrymeUtility.updateWithTarget(rollData)
|
||||||
|
return rollData
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static updateWithTarget(rollData) {
|
||||||
|
let target = EcrymeUtility.getTarget()
|
||||||
|
if (target) {
|
||||||
|
rollData.defenderTokenId = target.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async createChatWithRollMode(name, chatOptions) {
|
||||||
|
return await this.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async confirmDelete(actorSheet, li) {
|
||||||
|
let itemId = li.data("item-id");
|
||||||
|
let msgTxt = "<p>Are you sure to remove this Item ?";
|
||||||
|
let buttons = {
|
||||||
|
delete: {
|
||||||
|
icon: '<i class="fas fa-check"></i>',
|
||||||
|
label: "Yes, remove it",
|
||||||
|
callback: () => {
|
||||||
|
actorSheet.actor.deleteEmbeddedDocuments("Item", [itemId]);
|
||||||
|
li.slideUp(200, () => actorSheet.render(false));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
icon: '<i class="fas fa-times"></i>',
|
||||||
|
label: "Cancel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msgTxt += "</p>";
|
||||||
|
let d = new Dialog({
|
||||||
|
title: "Confirm removal",
|
||||||
|
content: msgTxt,
|
||||||
|
buttons: buttons,
|
||||||
|
default: "cancel"
|
||||||
|
});
|
||||||
|
d.render(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
86
modules/dialogs/tedeum-roll-dialog.js
Normal file
86
modules/dialogs/tedeum-roll-dialog.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { EcrymeUtility } from "../common/ecryme-utility.js";
|
||||||
|
|
||||||
|
export class EcrymeRollDialog extends Dialog {
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async create(actor, rollData) {
|
||||||
|
|
||||||
|
let options = { classes: ["ecryme-roll-dialog"], width: 540, height: 'fit-content', 'z-index': 99999 }
|
||||||
|
let html = await renderTemplate('systems/fvtt-ecryme/templates/dialogs/roll-dialog-generic.hbs', rollData);
|
||||||
|
return new EcrymeRollDialog(actor, rollData, html, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
constructor(actor, rollData, html, options, close = undefined) {
|
||||||
|
let conf = {
|
||||||
|
title: game.i18n.localize("ECRY.ui.rolltitle"),
|
||||||
|
content: html,
|
||||||
|
buttons: {
|
||||||
|
roll: {
|
||||||
|
icon: '<i class="fas fa-check"></i>',
|
||||||
|
label: game.i18n.localize("ECRY.ui.roll"),
|
||||||
|
callback: () => { this.roll() }
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
icon: '<i class="fas fa-times"></i>',
|
||||||
|
label: game.i18n.localize("ECRY.ui.cancel"),
|
||||||
|
callback: () => { this.close() }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close: close
|
||||||
|
}
|
||||||
|
|
||||||
|
super(conf, options);
|
||||||
|
|
||||||
|
this.actor = actor;
|
||||||
|
this.rollData = rollData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
roll() {
|
||||||
|
EcrymeUtility.rollEcryme(this.rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async refreshDialog() {
|
||||||
|
const content = await renderTemplate("systems/fvtt-ecryme/templates/dialogs/roll-dialog-generic.hbs", this.rollData)
|
||||||
|
this.data.content = content
|
||||||
|
this.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
var dialog = this;
|
||||||
|
function onLoad() {
|
||||||
|
}
|
||||||
|
$(function () { onLoad(); });
|
||||||
|
|
||||||
|
html.find('#bonusMalusPerso').change((event) => {
|
||||||
|
this.rollData.bonusMalusPerso = Number(event.currentTarget.value)
|
||||||
|
})
|
||||||
|
html.find('#roll-difficulty').change((event) => {
|
||||||
|
this.rollData.difficulty = Number(event.currentTarget.value) || 0
|
||||||
|
})
|
||||||
|
html.find('#roll-specialization').change((event) => {
|
||||||
|
this.rollData.selectedSpecs = $('#roll-specialization').val()
|
||||||
|
})
|
||||||
|
html.find('#roll-trait-bonus').change((event) => {
|
||||||
|
this.rollData.traitsBonus = $('#roll-trait-bonus').val()
|
||||||
|
})
|
||||||
|
html.find('#roll-trait-malus').change((event) => {
|
||||||
|
this.rollData.traitsMalus = $('#roll-trait-malus').val()
|
||||||
|
})
|
||||||
|
html.find('#roll-select-transcendence').change((event) => {
|
||||||
|
this.rollData.skillTranscendence = Number($('#roll-select-transcendence').val())
|
||||||
|
})
|
||||||
|
html.find('#roll-use-spleen').change((event) => {
|
||||||
|
this.rollData.useSpleen = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
html.find('#roll-use-ideal').change((event) => {
|
||||||
|
this.rollData.useIdeal = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
185
modules/items/tedeum-item-sheet.js
Normal file
185
modules/items/tedeum-item-sheet.js
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
import { EcrymeUtility } from "../common/tedeum-utility.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend the basic ItemSheet with some very simple modifications
|
||||||
|
* @extends {ItemSheet}
|
||||||
|
*/
|
||||||
|
export class EcrymeItemSheet extends ItemSheet {
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static get defaultOptions() {
|
||||||
|
return mergeObject(super.defaultOptions, {
|
||||||
|
classes: ["fvtt-ecryme", "sheet", "item"],
|
||||||
|
template: "systems/fvtt-ecryme/templates/item-sheet.hbs",
|
||||||
|
dragDrop: [{ dragSelector: null, dropSelector: null }],
|
||||||
|
width: 620,
|
||||||
|
height: 580,
|
||||||
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "description" }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_getHeaderButtons() {
|
||||||
|
let buttons = super._getHeaderButtons();
|
||||||
|
// Add "Post to chat" button
|
||||||
|
// We previously restricted this to GM and editable items only. If you ever find this comment because it broke something: eh, sorry!
|
||||||
|
buttons.unshift(
|
||||||
|
{
|
||||||
|
class: "post",
|
||||||
|
icon: "fas fa-comment",
|
||||||
|
onclick: ev => { }
|
||||||
|
})
|
||||||
|
return buttons
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
setPosition(options = {}) {
|
||||||
|
const position = super.setPosition(options);
|
||||||
|
const sheetBody = this.element.find(".sheet-body");
|
||||||
|
const bodyHeight = position.height - 192;
|
||||||
|
sheetBody.css("height", bodyHeight);
|
||||||
|
if (this.item.type.includes('weapon')) {
|
||||||
|
position.width = 640;
|
||||||
|
}
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async getData() {
|
||||||
|
|
||||||
|
let formData = {
|
||||||
|
title: this.title,
|
||||||
|
id: this.id,
|
||||||
|
type: this.object.type,
|
||||||
|
img: this.object.img,
|
||||||
|
name: this.object.name,
|
||||||
|
editable: this.isEditable,
|
||||||
|
cssClass: this.isEditable ? "editable" : "locked",
|
||||||
|
system: duplicate(this.object.system),
|
||||||
|
config: duplicate(game.system.ecryme.config),
|
||||||
|
limited: this.object.limited,
|
||||||
|
options: this.options,
|
||||||
|
owner: this.document.isOwner,
|
||||||
|
description: await TextEditor.enrichHTML(this.object.system.description, { async: true }),
|
||||||
|
notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }),
|
||||||
|
isGM: game.user.isGM
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this.object.type == "archetype") {
|
||||||
|
formData.tarots = EcrymeUtility.getTarots()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.options.editable = !(this.object.origin == "embeddedItem");
|
||||||
|
console.log("ITEM DATA", formData, this);
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_getHeaderButtons() {
|
||||||
|
let buttons = super._getHeaderButtons();
|
||||||
|
buttons.unshift({
|
||||||
|
class: "post",
|
||||||
|
icon: "fas fa-comment",
|
||||||
|
onclick: ev => this.postItem()
|
||||||
|
});
|
||||||
|
return buttons
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
postItem() {
|
||||||
|
let chatData = duplicate(this.item)
|
||||||
|
if (this.actor) {
|
||||||
|
chatData.actor = { id: this.actor.id };
|
||||||
|
}
|
||||||
|
// Don't post any image for the item (which would leave a large gap) if the default image is used
|
||||||
|
if (chatData.img.includes("/blank.png")) {
|
||||||
|
chatData.img = null;
|
||||||
|
}
|
||||||
|
// JSON object for easy creation
|
||||||
|
chatData.jsondata = JSON.stringify(
|
||||||
|
{
|
||||||
|
compendium: "postedItem",
|
||||||
|
payload: chatData,
|
||||||
|
});
|
||||||
|
|
||||||
|
renderTemplate('systems/Ecryme/templates/post-item.html', chatData).then(html => {
|
||||||
|
let chatOptions = EcrymeUtility.chatDataSetup(html);
|
||||||
|
ChatMessage.create(chatOptions)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async viewSubitem(ev) {
|
||||||
|
let levelIndex = Number($(ev.currentTarget).parents(".item").data("level-index"))
|
||||||
|
let choiceIndex = Number($(ev.currentTarget).parents(".item").data("choice-index"))
|
||||||
|
let featureId = $(ev.currentTarget).parents(".item").data("feature-id")
|
||||||
|
|
||||||
|
let itemData = this.object.system.levels[levelIndex].choices[choiceIndex].features[featureId]
|
||||||
|
|
||||||
|
if (itemData.name != 'None') {
|
||||||
|
let item = await Item.create(itemData, { temporary: true });
|
||||||
|
item.system.origin = "embeddedItem";
|
||||||
|
new EcrymeItemSheet(item).render(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async deleteSubitem(ev) {
|
||||||
|
let field = $(ev.currentTarget).data('type');
|
||||||
|
let idx = Number($(ev.currentTarget).data('index'));
|
||||||
|
let oldArray = this.object.system[field];
|
||||||
|
let itemData = this.object.system[field][idx];
|
||||||
|
if (itemData.name != 'None') {
|
||||||
|
let newArray = [];
|
||||||
|
for (var i = 0; i < oldArray.length; i++) {
|
||||||
|
if (i != idx) {
|
||||||
|
newArray.push(oldArray[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.object.update({ [`system.${field}`]: newArray });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
// Everything below here is only needed if the sheet is editable
|
||||||
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
|
|
||||||
|
// Update Inventory Item
|
||||||
|
html.find('.item-edit').click(ev => {
|
||||||
|
const li = $(ev.currentTarget).parents(".item");
|
||||||
|
const item = this.object.options.actor.getOwnedItem(li.data("item-id"));
|
||||||
|
item.sheet.render(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
html.find('.delete-subitem').click(ev => {
|
||||||
|
this.deleteSubitem(ev);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update Inventory Item
|
||||||
|
html.find('.item-delete').click(ev => {
|
||||||
|
const li = $(ev.currentTarget).parents(".item");
|
||||||
|
let itemId = li.data("item-id");
|
||||||
|
let itemType = li.data("item-type");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
get template() {
|
||||||
|
let type = this.item.type;
|
||||||
|
return `systems/fvtt-ecryme/templates/items/item-${type}-sheet.hbs`
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
_updateObject(event, formData) {
|
||||||
|
return this.object.update(formData)
|
||||||
|
}
|
||||||
|
}
|
27
modules/items/tedeum-item.js
Normal file
27
modules/items/tedeum-item.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { EcrymeUtility } from "../common/ecryme-utility.js";
|
||||||
|
|
||||||
|
export const defaultItemImg = {
|
||||||
|
weapon: "systems/fvtt-ecryme/images/icons/icon_weapon.webp",
|
||||||
|
equipment: "systems/fvtt-ecryme/images/icons/icon_equipment.webp",
|
||||||
|
contact: "systems/fvtt-ecryme/images/icons/icon_contact.webp",
|
||||||
|
boheme: "systems/fvtt-ecryme/images/icons/icon_boheme.webp",
|
||||||
|
trait: "systems/fvtt-ecryme/images/icons/icon_trait.webp",
|
||||||
|
annency: "systems/fvtt-ecryme/images/icons/icon_annency.webp",
|
||||||
|
skill: "systems/fvtt-ecryme/images/icons/icon_skill.webp",
|
||||||
|
specialization: "systems/fvtt-ecryme/images/icons/icon_spec.webp"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend the basic ItemSheet with some very simple modifications
|
||||||
|
* @extends {ItemSheet}
|
||||||
|
*/
|
||||||
|
export class EcrymeItem extends Item {
|
||||||
|
|
||||||
|
constructor(data, context) {
|
||||||
|
if (!data.img) {
|
||||||
|
data.img = defaultItemImg[data.type];
|
||||||
|
}
|
||||||
|
super(data, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
147
modules/tedeum-main.js
Normal file
147
modules/tedeum-main.js
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/**
|
||||||
|
* Ecryme system
|
||||||
|
* Author: Uberwald
|
||||||
|
* Software License: Prop
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
// Import Modules
|
||||||
|
import { EcrymeActor } from "./actors/ecryme-actor.js";
|
||||||
|
import { EcrymeItemSheet } from "./items/tedeum-item-sheet.js";
|
||||||
|
import { EcrymeActorSheet } from "./actors/ecryme-actor-sheet.js";
|
||||||
|
import { EcrymeAnnencySheet } from "./actors/ecryme-annency-sheet.js";
|
||||||
|
import { EcrymeUtility } from "./common/ecryme-utility.js";
|
||||||
|
import { EcrymeCombat } from "./app/ecryme-combat.js";
|
||||||
|
import { EcrymeItem } from "./items/ecryme-item.js";
|
||||||
|
import { EcrymeHotbar } from "./app/ecryme-hotbar.js"
|
||||||
|
import { EcrymeCharacterSummary } from "./app/ecryme-summary-app.js"
|
||||||
|
import { ECRYME_CONFIG } from "./common/ecryme-config.js"
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/* Foundry VTT Initialization */
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/************************************************************************************/
|
||||||
|
Hooks.once("init", async function () {
|
||||||
|
|
||||||
|
console.log(`Initializing Ecryme RPG`);
|
||||||
|
|
||||||
|
game.system.ecryme = {
|
||||||
|
config: ECRYME_CONFIG,
|
||||||
|
EcrymeHotbar
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
// preload handlebars templates
|
||||||
|
EcrymeUtility.preloadHandlebarsTemplates();
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
// Set an initiative formula for the system
|
||||||
|
CONFIG.Combat.initiative = {
|
||||||
|
formula: "1d6",
|
||||||
|
decimals: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
game.socket.on("system.fvtt-ecryme", data => {
|
||||||
|
EcrymeUtility.onSocketMesssage(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
// Define custom Entity classes
|
||||||
|
CONFIG.Combat.documentClass = EcrymeCombat
|
||||||
|
CONFIG.Actor.documentClass = EcrymeActor
|
||||||
|
CONFIG.Item.documentClass = EcrymeItem
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
// Register sheet application classes
|
||||||
|
Actors.unregisterSheet("core", ActorSheet);
|
||||||
|
Actors.registerSheet("fvtt-ecryme", EcrymeActorSheet, { types: ["pc"], makeDefault: true });
|
||||||
|
Actors.registerSheet("fvtt-ecryme", EcrymeActorSheet, { types: ["npc"], makeDefault: true });
|
||||||
|
Actors.registerSheet("fvtt-ecryme", EcrymeAnnencySheet, { types: ["annency"], makeDefault: false });
|
||||||
|
|
||||||
|
Items.unregisterSheet("core", ItemSheet);
|
||||||
|
Items.registerSheet("fvtt-ecryme", EcrymeItemSheet, { makeDefault: true });
|
||||||
|
|
||||||
|
EcrymeUtility.init()
|
||||||
|
|
||||||
|
console.log("Babele INIT!")
|
||||||
|
Babele.get().setSystemTranslationsDir("translated")
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
function welcomeMessage() {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
ChatMessage.create({
|
||||||
|
user: game.user.id,
|
||||||
|
whisper: [game.user.id],
|
||||||
|
content: `<div id="welcome-message-ecryme"><span class="rdd-roll-part">
|
||||||
|
<strong>Bienvenu dans Ecryme !</strong>` });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
// Register world usage statistics
|
||||||
|
function registerUsageCount(registerKey) {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
game.settings.register(registerKey, "world-key", {
|
||||||
|
name: "Unique world key",
|
||||||
|
scope: "world",
|
||||||
|
config: false,
|
||||||
|
default: "",
|
||||||
|
type: String
|
||||||
|
});
|
||||||
|
|
||||||
|
let worldKey = game.settings.get(registerKey, "world-key")
|
||||||
|
if (worldKey == undefined || worldKey == "") {
|
||||||
|
worldKey = randomID(32)
|
||||||
|
game.settings.set(registerKey, "world-key", worldKey)
|
||||||
|
}
|
||||||
|
// Simple API counter
|
||||||
|
let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
|
||||||
|
//$.ajaxSetup({
|
||||||
|
//headers: { 'Access-Control-Allow-Origin': '*' }
|
||||||
|
//})
|
||||||
|
$.ajax(regURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/* Foundry VTT Initialization */
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
Hooks.once("ready", function () {
|
||||||
|
|
||||||
|
// User warning
|
||||||
|
if (!game.user.isGM && game.user.character == undefined) {
|
||||||
|
ui.notifications.info("Attention ! Aucun personnage relié au joueur !");
|
||||||
|
ChatMessage.create({
|
||||||
|
content: "<b>WARNING</b> Le joueur " + game.user.name + " n'est pas relié à un personnage !",
|
||||||
|
user: game.user._id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
registerUsageCount(game.system.id)
|
||||||
|
welcomeMessage();
|
||||||
|
EcrymeUtility.ready()
|
||||||
|
EcrymeCharacterSummary.ready()
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/* Foundry VTT Initialization */
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
Hooks.on("chatMessage", (html, content, msg) => {
|
||||||
|
if (content[0] == '/') {
|
||||||
|
let regExp = /(\S+)/g;
|
||||||
|
let commands = content.match(regExp);
|
||||||
|
if (game.system.ecryme.commands.processChatCommand(commands, content, msg)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
1409
postcss/tedeum.css
Normal file
1409
postcss/tedeum.css
Normal file
File diff suppressed because it is too large
Load Diff
1389
styles/tedeum.css
Normal file
1389
styles/tedeum.css
Normal file
File diff suppressed because it is too large
Load Diff
56
system.json
Normal file
56
system.json
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"description": "Te Deum Pour Un Massacre",
|
||||||
|
"esmodules": [
|
||||||
|
"modules/tedeum-main.js"
|
||||||
|
],
|
||||||
|
"gridDistance": 1,
|
||||||
|
"gridUnits": "m",
|
||||||
|
"languages": [
|
||||||
|
{
|
||||||
|
"lang": "fr",
|
||||||
|
"name": "French",
|
||||||
|
"path": "lang/fr.json",
|
||||||
|
"flags": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Uberwald",
|
||||||
|
"flags": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packs": [
|
||||||
|
{
|
||||||
|
"label": "Equipment",
|
||||||
|
"type": "Item",
|
||||||
|
"name": "equipment",
|
||||||
|
"path": "packs/equipment",
|
||||||
|
"system": "fvtt-ecryme",
|
||||||
|
"flags": {},
|
||||||
|
"ownership": {
|
||||||
|
"PLAYER": "OBSERVER",
|
||||||
|
"ASSISTANT": "OWNER"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "LICENSE.txt",
|
||||||
|
"manifest": "https://www.uberwald.me/gitea/public/fvtt-te-deum/raw/branch/master/system.json",
|
||||||
|
"compatibility": {
|
||||||
|
"minimum": "10",
|
||||||
|
"verified": "11"
|
||||||
|
},
|
||||||
|
"id": "fvtt-tedeum",
|
||||||
|
"primaryTokenAttribute": "secondary.health",
|
||||||
|
"secondaryTokenAttribute": "secondary.delirium",
|
||||||
|
"socket": true,
|
||||||
|
"styles": [
|
||||||
|
"styles/tedeum.css"
|
||||||
|
],
|
||||||
|
"relationships": {
|
||||||
|
},
|
||||||
|
"title": "Te Deum pour Un Massacre, le Jeu de Rôles",
|
||||||
|
"url": "https://www.uberwald.me/gitea/public/fvtt-tedeum",
|
||||||
|
"version": "11.0.0",
|
||||||
|
"download": "https://www.uberwald.me/gitea/public/fvtt-tedeum/archive/fvtt-tedeum-v11.0.0.zip",
|
||||||
|
"background": ""
|
||||||
|
}
|
312
template.json
Normal file
312
template.json
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
{
|
||||||
|
"Actor": {
|
||||||
|
"types": [
|
||||||
|
"pc","annency", "npc"
|
||||||
|
],
|
||||||
|
"templates": {
|
||||||
|
"biodata": {
|
||||||
|
"biodata": {
|
||||||
|
"age": "",
|
||||||
|
"size": "",
|
||||||
|
"lieunaissance": "",
|
||||||
|
"nationalite": "",
|
||||||
|
"profession": "",
|
||||||
|
"residence": "",
|
||||||
|
"milieusocial": "",
|
||||||
|
"poids": "",
|
||||||
|
"cheveux": "",
|
||||||
|
"sexe": "",
|
||||||
|
"yeux": "",
|
||||||
|
"enfance": "",
|
||||||
|
"description": "",
|
||||||
|
"gmnotes": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"core": {
|
||||||
|
"subactors": [],
|
||||||
|
"equipmentfree": "",
|
||||||
|
"skills": {
|
||||||
|
"physical": {
|
||||||
|
"name": "ECRY.ui.physical",
|
||||||
|
"skilllist": {
|
||||||
|
"athletics": {
|
||||||
|
"name": "ECRY.ui.athletics",
|
||||||
|
"max": 0,
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"driving": {
|
||||||
|
"name": "ECRY.ui.driving",
|
||||||
|
"max": 0,
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"fencing": {
|
||||||
|
"name": "ECRY.ui.fencing",
|
||||||
|
"max": 0,
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"brawling": {
|
||||||
|
"name": "ECRY.ui.brawling",
|
||||||
|
"max": 0,
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"shooting": {
|
||||||
|
"name": "ECRY.ui.shooting",
|
||||||
|
"max": 0,
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mental": {
|
||||||
|
"name": "ECRY.ui.mental",
|
||||||
|
"skilllist": {
|
||||||
|
"anthropomecanology": {
|
||||||
|
"name": "ECRY.ui.anthropomecanology",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"ecrymology": {
|
||||||
|
"name": "ECRY.ui.ecrymology",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"traumatology": {
|
||||||
|
"name": "ECRY.ui.traumatology",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"traversology": {
|
||||||
|
"name": "ECRY.ui.traversology",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"urbatechnology": {
|
||||||
|
"name": "ECRY.ui.urbatechnology",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"social": {
|
||||||
|
"name": "ECRY.ui.social",
|
||||||
|
"skilllist": {
|
||||||
|
"quibbling": {
|
||||||
|
"name": "ECRY.ui.quibbling",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"creativity": {
|
||||||
|
"name": "ECRY.ui.creativity",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"loquacity": {
|
||||||
|
"name": "ECRY.ui.loquacity",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"guile": {
|
||||||
|
"name": "ECRY.ui.guile",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"performance": {
|
||||||
|
"name": "ECRY.ui.performance",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"impacts": {
|
||||||
|
"physical": {
|
||||||
|
"superficial": 0,
|
||||||
|
"light": 0,
|
||||||
|
"serious": 0,
|
||||||
|
"major": 0
|
||||||
|
},
|
||||||
|
"mental": {
|
||||||
|
"superficial": 0,
|
||||||
|
"light": 0,
|
||||||
|
"serious": 0,
|
||||||
|
"major": 0
|
||||||
|
},
|
||||||
|
"social": {
|
||||||
|
"superficial": 0,
|
||||||
|
"light": 0,
|
||||||
|
"serious": 0,
|
||||||
|
"major": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cephaly": {
|
||||||
|
"name": "ECRY.ui.cephaly",
|
||||||
|
"skilllist": {
|
||||||
|
"elegy": {
|
||||||
|
"name": "ECRY.ui.elegy",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"entelechy": {
|
||||||
|
"name": "ECRY.ui.entelechy",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"mekany": {
|
||||||
|
"name": "ECRY.ui.mekany",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"psyche": {
|
||||||
|
"name": "ECRY.ui.psyche",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
},
|
||||||
|
"scoria": {
|
||||||
|
"name": "ECRY.ui.scoria",
|
||||||
|
"value": 0,
|
||||||
|
"max": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"internals": {
|
||||||
|
"confrontbonus": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npccore": {
|
||||||
|
"npctype": "",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"annency": {
|
||||||
|
"base": {
|
||||||
|
"iscollective": false,
|
||||||
|
"ismultiple": false,
|
||||||
|
"characters": [],
|
||||||
|
"location": {"1": "", "2": "", "3":"", "4":"", "5":"" },
|
||||||
|
"description": "",
|
||||||
|
"enhancements": ""
|
||||||
|
},
|
||||||
|
"boheme": {
|
||||||
|
"name": "",
|
||||||
|
"ideals": "",
|
||||||
|
"politic": "",
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"annency": {
|
||||||
|
"templates": [
|
||||||
|
"annency"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"npc": {
|
||||||
|
"templates": [
|
||||||
|
"biodata",
|
||||||
|
"core"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pc": {
|
||||||
|
"templates": [
|
||||||
|
"biodata",
|
||||||
|
"core"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Item": {
|
||||||
|
"types": [
|
||||||
|
"equipment",
|
||||||
|
"trait",
|
||||||
|
"weapon",
|
||||||
|
"specialization",
|
||||||
|
"maneuver"
|
||||||
|
],
|
||||||
|
"templates": {
|
||||||
|
"common": {
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"equipement": {
|
||||||
|
"weight": 0,
|
||||||
|
"cost": 0,
|
||||||
|
"costunit": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"maneuver": {
|
||||||
|
"templates": [
|
||||||
|
"common"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"confrontation": {
|
||||||
|
"templates": [
|
||||||
|
"common"
|
||||||
|
],
|
||||||
|
"attackerId": "",
|
||||||
|
"defenserId": "",
|
||||||
|
"rolllist": [],
|
||||||
|
"bonusexecution": 0,
|
||||||
|
"bonuspreservation": 0
|
||||||
|
},
|
||||||
|
"equipment": {
|
||||||
|
"templates": [
|
||||||
|
"common",
|
||||||
|
"equipement"
|
||||||
|
],
|
||||||
|
"quantity": 1,
|
||||||
|
"weight": 0
|
||||||
|
},
|
||||||
|
"trait": {
|
||||||
|
"templates": [
|
||||||
|
"common"
|
||||||
|
],
|
||||||
|
"traitype": "normal",
|
||||||
|
"level": 1
|
||||||
|
},
|
||||||
|
"weapon": {
|
||||||
|
"templates": [
|
||||||
|
"common",
|
||||||
|
"equipement"
|
||||||
|
],
|
||||||
|
"weapontype": "melee",
|
||||||
|
"effect": 0
|
||||||
|
},
|
||||||
|
"specialization": {
|
||||||
|
"bonus": 2,
|
||||||
|
"templates": [
|
||||||
|
"common"
|
||||||
|
],
|
||||||
|
"skillkey": ""
|
||||||
|
},
|
||||||
|
"scar": {
|
||||||
|
"templates": [
|
||||||
|
"common"
|
||||||
|
],
|
||||||
|
"skillcategory": [
|
||||||
|
"physical",
|
||||||
|
"mental",
|
||||||
|
"social",
|
||||||
|
"cephalie"
|
||||||
|
],
|
||||||
|
"scarLevel": 1
|
||||||
|
},
|
||||||
|
"annency": {
|
||||||
|
"templates": [
|
||||||
|
"common"
|
||||||
|
],
|
||||||
|
"collective": false,
|
||||||
|
"multiple": false,
|
||||||
|
"improvements": ""
|
||||||
|
},
|
||||||
|
"boheme": {
|
||||||
|
"templates": [
|
||||||
|
"common"
|
||||||
|
],
|
||||||
|
"ideals": "",
|
||||||
|
"political": ""
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"templates": [
|
||||||
|
"common"
|
||||||
|
],
|
||||||
|
"attitude": "neutral",
|
||||||
|
"organization": "",
|
||||||
|
"location": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
385
templates/actors/actor-sheet.hbs
Normal file
385
templates/actors/actor-sheet.hbs
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
|
||||||
|
{{!-- Sheet Header --}}
|
||||||
|
<header class="sheet-header">
|
||||||
|
<div class="header-fields">
|
||||||
|
<div class="flexrow">
|
||||||
|
|
||||||
|
<div class="profile-img-container">
|
||||||
|
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexcol">
|
||||||
|
<h1 class="charname margin-right"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<ul>
|
||||||
|
<li class="flexrow item" data-item-id="{{spleen.id}}">
|
||||||
|
<label class="item-name-label-medium">Spleen :</label>
|
||||||
|
<label class="item-name-label-long">{{spleen.name}}</label>
|
||||||
|
<div class="item-filler"> </div>
|
||||||
|
{{#if spleen}}
|
||||||
|
<div class="item-controls item-controls-fixed-full">
|
||||||
|
<a class="item-control item-add" data-type="trait" title="Create Trait"><i class="fas fa-plus"></i></a>
|
||||||
|
<a class="item-control item-edit" data-type="trait" title="Edit Item"><i class="fas fa-edit"></i></a>
|
||||||
|
<a class="item-control item-add" data-type="trait" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</li>
|
||||||
|
<li class="item flexrow" data-item-id="{{ideal.id}}">
|
||||||
|
<label class="item-name-label-medium">Ideal :</label>
|
||||||
|
<label class="item-name-label-long">{{ideal.name}}</label>
|
||||||
|
<div class="item-filler"> </div>
|
||||||
|
{{#if ideal}}
|
||||||
|
<div class="item-controls item-controls-fixed-full">
|
||||||
|
<a class="item-control item-add" data-type="trait" title="Create Trait"><i class="fas fa-plus"></i></a>
|
||||||
|
<a class="item-control item-edit" data-type="trait" title="Edit Item"><i class="fas fa-edit"></i></a>
|
||||||
|
<a class="item-control item-add" data-type="trait" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{!-- Sheet Tab Navigation --}}
|
||||||
|
<nav class="sheet-tabs tabs" data-group="primary">
|
||||||
|
<a class="item" data-tab="competences">{{localize "ECRY.ui.skills"}}</a>
|
||||||
|
<a class="item" data-tab="traits">{{localize "ECRY.ui.traits"}}</a>
|
||||||
|
<a class="item" data-tab="combat">{{localize "ECRY.ui.healthcombat"}}</a>
|
||||||
|
{{#if hasCephaly}}
|
||||||
|
<a class="item" data-tab="cephaly">{{localize "ECRY.ui.cephaly"}}</a>
|
||||||
|
{{/if}}
|
||||||
|
<a class="item" data-tab="equipements">{{localize "ECRY.ui.equipment"}}</a>
|
||||||
|
<a class="item" data-tab="biodata">{{localize "ECRY.ui.bionotes"}}</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
|
||||||
|
{{!-- Skills Tab --}}
|
||||||
|
<div class="tab competences" data-group="primary" data-tab="competences">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="grid grid-3col">
|
||||||
|
|
||||||
|
{{#each skills as |category categkey|}}
|
||||||
|
<div>
|
||||||
|
<ul class="stat-list alternate-list item-list">
|
||||||
|
<li class="item flexrow list-item items-title-bg">
|
||||||
|
<span class="item-name-label-header impact-title">
|
||||||
|
<h3><label class="items-title-text">{{localize category.name}} ({{valueAtIndex @root.impactsMalus
|
||||||
|
categkey}})</label></h3>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{{#each category.skilllist as |skill skillkey|}}
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-long">
|
||||||
|
<a class="roll-skill-confront" data-category-key="{{categkey}}" data-skill-key="{{skillkey}}">
|
||||||
|
<i class="fa-regular fa-swords"></i>
|
||||||
|
</a>
|
||||||
|
<a class="roll-skill" data-category-key="{{categkey}}" data-skill-key="{{skillkey}}">
|
||||||
|
<i class="fa-solid fa-dice-d6"></i>
|
||||||
|
{{localize skill.name}}
|
||||||
|
</a></span>
|
||||||
|
<select class="item-field-label-short" type="text"
|
||||||
|
name="system.skills.{{categkey}}.skilllist.{{skillkey}}.value" value="{{skill.value}}"
|
||||||
|
data-dtype="Number">
|
||||||
|
{{#select skill.value}}
|
||||||
|
{{#each @root.config.skillLevel as |level key| }}
|
||||||
|
<option value="{{level}}">{{level}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<ul class="ul-level1">
|
||||||
|
{{#each skill.spec as |spec idx|}}
|
||||||
|
<li class="item flexrow list-item" data-item-id="{{spec._id}}" data-item-type="specialization">
|
||||||
|
<a class="roll-spec" data-category-key="{{categkey}}" data-skill-key="{{skillkey}}" data-spec-id="{{spec._id}}">
|
||||||
|
<i class="fa-solid fa-dice-d6"></i>
|
||||||
|
{{spec.name}}
|
||||||
|
</a>
|
||||||
|
<div class="item-controls item-controls-fixed">
|
||||||
|
<a class="item-control item-edit" data-type="specialization" title="Edit Item"><i
|
||||||
|
class="fas fa-edit"></i></a>
|
||||||
|
<a class="item-control item-delete" data-type="specialization" title="Delete Item"><i
|
||||||
|
class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if hasCephaly}}
|
||||||
|
{{!-- Cephaly Tab --}}
|
||||||
|
<div class="tab cephaly" data-group="primary" data-tab="cephaly">
|
||||||
|
|
||||||
|
<div class="grid grid-2col">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<h3>{{localize "ECRY.ui.cephaly"}}</h3>
|
||||||
|
<ul class="stat-list alternate-list item-list">
|
||||||
|
{{#each cephalySkills as |skill skillkey|}}
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-long">
|
||||||
|
<a class="roll-cephaly" data-category-key="cephaly" data-skill-key="{{skillkey}}">
|
||||||
|
<i class="fa-solid fa-dice-d6"></i>
|
||||||
|
{{localize skill.name}}
|
||||||
|
</a></span>
|
||||||
|
<select class="item-field-label-short" type="text" name="system.cephaly.skilllist.{{skillkey}}.value"
|
||||||
|
value="{{skill.value}}" data-dtype="Number">
|
||||||
|
{{#select skill.value}}
|
||||||
|
{{#each @root.config.skillLevel as |level key| }}
|
||||||
|
<option value="{{level}}">{{level}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{#if annency}}
|
||||||
|
<h3>{{localize "ECRY.ui.annency"}} : <a class="open-annency" data-annency-id="{{annency.id}}">{{annency.name}}<i class="fas fa-edit"></i></a></h3>
|
||||||
|
<ul class="stat-list alternate-list item-list">
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-long">
|
||||||
|
{{annency.system.base.description}}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="tab traits" data-group="primary" data-tab="traits">
|
||||||
|
|
||||||
|
<ul class="item-list alternate-list">
|
||||||
|
<li class="item flexrow list-item items-title-bg">
|
||||||
|
<span class="item-name-label-header-long2">
|
||||||
|
<h3><label class="item-name-label-header-long2">Traits</label></h3>
|
||||||
|
</span>
|
||||||
|
<span class="item-field-label-short">
|
||||||
|
<label class="item-field-label-short">Niveau</label>
|
||||||
|
</span>
|
||||||
|
<div class="item-controls item-controls-fixed">
|
||||||
|
<a class="item-control item-add" data-type="trait" title="Create Trait"><i class="fas fa-plus"></i></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{#each traits as |trait key|}}
|
||||||
|
<li class="item flexrow list-item list-item-shadow" data-item-id="{{trait._id}}">
|
||||||
|
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
|
||||||
|
src="{{trait.img}}" /></a>
|
||||||
|
<span class="item-name-label-long2">{{trait.name}}</span>
|
||||||
|
<span class="item-field-label-short"><label>{{trait.system.level}}</label></span>
|
||||||
|
|
||||||
|
<div class="item-filler"> </div>
|
||||||
|
<div class="item-controls item-controls-fixed">
|
||||||
|
<a class="item-control item-delete" title="Delete trait"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab combat" data-group="primary" data-tab="combat">
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
{{> systems/fvtt-ecryme/templates/actors/partial-impacts.hbs impacts=system.impacts.physical
|
||||||
|
impacttype="physical" impactMalus=impactsMalus.physical}}
|
||||||
|
{{> systems/fvtt-ecryme/templates/actors/partial-impacts.hbs impacts=system.impacts.mental
|
||||||
|
impacttype="mental" impactMalus=impactsMalus.mental}}
|
||||||
|
{{> systems/fvtt-ecryme/templates/actors/partial-impacts.hbs impacts=system.impacts.social
|
||||||
|
impacttype="social" impactMalus=impactsMalus.social}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="item-list alternate-list">
|
||||||
|
<li class="item flexrow list-item items-title-bg">
|
||||||
|
<span class="item-name-label-header-long2">
|
||||||
|
<h3><label class="item-name-label-header-long2">{{localize "ECRY.ui.weapons"}}</label></h3>
|
||||||
|
</span>
|
||||||
|
<span class="item-field-label-medium">
|
||||||
|
<label class="item-field-label-medium">{{localize "ECRY.ui.type"}}</label>
|
||||||
|
</span>
|
||||||
|
<span class="item-field-label-medium">
|
||||||
|
<label class="item-field-label-medium">{{localize "ECRY.ui.effect"}}</label>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{{#each weapons as |weapon key|}}
|
||||||
|
<li class="item flexrow list-item list-item-shadow" data-item-id="{{weapon._id}}">
|
||||||
|
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
|
||||||
|
src="{{weapon.img}}" /></a>
|
||||||
|
<span class="item-name-label-long2">
|
||||||
|
<a class="roll-weapon-confront" data-category-key="{{categkey}}" data-skill-key="{{skillkey}}">
|
||||||
|
<i class="fa-regular fa-swords"></i>
|
||||||
|
{{weapon.name}}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span class="item-field-label-medium">{{localize (concat "ECRY.ui." weapon.system.weapontype)}}</span>
|
||||||
|
<span class="item-field-label-medium">{{weapon.system.effect}}</span>
|
||||||
|
|
||||||
|
<div class="item-filler"> </div>
|
||||||
|
<div class="item-controls item-controls-fixed">
|
||||||
|
<a class="item-control item-delete" title="Delete weapon"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="item-list alternate-list">
|
||||||
|
<li class="item flexrow list-item items-title-bg">
|
||||||
|
<span class="item-name-label-header-long2">
|
||||||
|
<h3><label class="item-name-label-header-long2">{{localize "ECRY.ui.maneuvers"}}</label></h3>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{{#each maneuvers as |maneuver key|}}
|
||||||
|
<li class="item flexrow list-item list-item-shadow" data-item-id="{{maneuver._id}}">
|
||||||
|
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
|
||||||
|
src="{{maneuver.img}}" /></a>
|
||||||
|
<span class="item-name-label-long2">
|
||||||
|
{{maneuver.name}}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="item-filler"> </div>
|
||||||
|
<div class="item-controls item-controls-fixed">
|
||||||
|
<a class="item-control item-delete" title="Delete maneuver"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{!-- Equipement Tab --}}
|
||||||
|
<div class="tab equipements" data-group="primary" data-tab="equipements">
|
||||||
|
|
||||||
|
<span class="item-name-label-header items-title-bg">
|
||||||
|
<h3><label class="items-title-text">{{localize "ECRY.ui.equipmentfree"}}</label></h3>
|
||||||
|
</span>
|
||||||
|
<div class="form-group small-editor">
|
||||||
|
{{editor equipementlibre target="system.equipmentfree" button=true owner=owner editable=editable}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="item-list alternate-list">
|
||||||
|
<li class="item flexrow list-item items-title-bg">
|
||||||
|
<span class="item-name-label-header">
|
||||||
|
<h3><label class="items-title-text">{{localize "ECRY.ui.equipment"}}s</label></h3>
|
||||||
|
</span>
|
||||||
|
<span class="item-field-label-medium">
|
||||||
|
<label class="item-field-label-medium">{{localize "ECRY.ui.weight"}}</label>
|
||||||
|
</span>
|
||||||
|
<div class="item-filler"> </div>
|
||||||
|
<div class="item-controls item-controls-fixed">
|
||||||
|
<a class="item-control item-add" data-type="equipment" title="Create Item"><i class="fas fa-plus"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
{{#each equipments as |equip key|}}
|
||||||
|
<li class="item list-item flexrow list-item-shadow" data-item-id="{{equip._id}}">
|
||||||
|
<a class="item-edit item-name-img" title="Edit Item"><img class="sheet-competence-img"
|
||||||
|
src="{{equip.img}}" /></a>
|
||||||
|
<span class="item-name-label">{{equip.name}}</span>
|
||||||
|
<span class="item-field-label-medium">{{equip.system.weight}}</span>
|
||||||
|
|
||||||
|
<div class="item-filler"> </div>
|
||||||
|
<div class="item-controls item-controls-fixed">
|
||||||
|
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{!-- Biography Tab --}}
|
||||||
|
<div class="tab biodata" data-group="primary" data-tab="biodata">
|
||||||
|
|
||||||
|
<div class="grid grid-2col">
|
||||||
|
<div>
|
||||||
|
<ul class="item-list alternate-list">
|
||||||
|
<li class="item flexrow">
|
||||||
|
<label class="item-name-label-medium">{{localize "ECRY.ui.bornplace"}}</label>
|
||||||
|
<input type="text" class="" name="system.biodata.lieunaissance" value="{{system.biodata.lieunaissance}}"
|
||||||
|
data-dtype="String" />
|
||||||
|
</li>
|
||||||
|
<li class="item flexrow">
|
||||||
|
<label class="item-name-label-medium">Age</label>
|
||||||
|
<input type="text" class="" name="system.biodata.age" value="{{system.biodata.age}}"
|
||||||
|
data-dtype="String" />
|
||||||
|
</li>
|
||||||
|
<li class="item flexrow">
|
||||||
|
<label class="item-name-label-medium">Profession</label>
|
||||||
|
<input type="text" class="" name="system.biodata.profession" value="{{system.biodata.profession}}"
|
||||||
|
data-dtype="String" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li class="item flexrow">
|
||||||
|
<label class="item-name-label-medium">{{localize "ECRY.ui.residence"}}</label>
|
||||||
|
<input type="text" class="" name="system.biodata.residence" value="{{system.biodata.residence}}"
|
||||||
|
data-dtype="String" />
|
||||||
|
</li>
|
||||||
|
<li class="item flexrow">
|
||||||
|
<label class="item-name-label-medium">{{localize "ECRY.ui.origin"}}</label>
|
||||||
|
<input type="text" class="" name="system.biodata.nationalite" value="{{system.biodata.nationalite}}"
|
||||||
|
data-dtype="String" />
|
||||||
|
</li>
|
||||||
|
<li class="item flexrow">
|
||||||
|
<label class="item-name-label-medium">{{localize "ECRY.ui.childhood"}}</label>
|
||||||
|
<input type="text" class="" name="system.biodata.enfance" value="{{system.biodata.enfance}}"
|
||||||
|
data-dtype="String" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<span class="item-name-label-header items-title-bg">
|
||||||
|
<h3><label class="items-title-text">Background</label></h3>
|
||||||
|
</span>
|
||||||
|
<div class="form-group editor">
|
||||||
|
{{editor description target="system.biodata.description" button=true owner=owner
|
||||||
|
editable=editable}}
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<span class="item-name-label-header items-title-bg">
|
||||||
|
<h3><label class="items-title-text">Notes</label></h3>
|
||||||
|
</span>
|
||||||
|
<div class="form-group editor">
|
||||||
|
{{editor notes target="system.biodata.notes" button=true owner=owner editable=editable}}
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</form>
|
138
templates/actors/annency-sheet.hbs
Normal file
138
templates/actors/annency-sheet.hbs
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
|
||||||
|
{{!-- Sheet Header --}}
|
||||||
|
<header class="sheet-header">
|
||||||
|
<div class="header-fields">
|
||||||
|
<div class="flexrow">
|
||||||
|
|
||||||
|
<div class="profile-img-container">
|
||||||
|
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexcol">
|
||||||
|
<h1 class="charname margin-right"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<ul>
|
||||||
|
<li class="flexrow item" data-item-id="{{spleen.id}}">
|
||||||
|
<label class="item-name-label-medium">Description :</label>
|
||||||
|
<textarea class="textarea-default" rows="3" name="system.base.description">{{system.base.description}}</textarea>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{!-- Sheet Tab Navigation --}}
|
||||||
|
<nav class="sheet-tabs tabs" data-group="primary">
|
||||||
|
{{#if hasCephaly}}
|
||||||
|
<a class="item" data-tab="annency">{{localize "ECRY.ui.annency"}}</a>
|
||||||
|
{{/if}}
|
||||||
|
{{#if hasBoheme}}
|
||||||
|
<a class="item" data-tab="boheme">{{localize "ECRY.ui.boheme"}}</a>
|
||||||
|
{{/if}}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
|
||||||
|
{{#if hasCephaly}}
|
||||||
|
{{!-- Cephaly Tab --}}
|
||||||
|
<div class="tab annency" data-group="primary" data-tab="annency">
|
||||||
|
|
||||||
|
<div class="grid grid-2col">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<h3>{{localize "ECRY.ui.annency"}}</h3>
|
||||||
|
<ul class="stat-list alternate-list item-list">
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-short">
|
||||||
|
{{localize "ECRY.ui.iscollective"}}
|
||||||
|
</span>
|
||||||
|
<input type="checkbox" class="item-field-label-short" name="system.base.iscollective"
|
||||||
|
value="{{system.base.iscollective}}" {{checked system.base.iscollective}} />
|
||||||
|
<span class="item-name-label-short">
|
||||||
|
{{localize "ECRY.ui.ismultiple"}}
|
||||||
|
</span>
|
||||||
|
<input type="checkbox" class="item-field-label-short" name="system.base.ismultiple"
|
||||||
|
value="{{system.base.ismultiple}}" {{checked system.base.ismultiple}} />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>{{localize "ECRY.ui.characters"}}</h3>
|
||||||
|
<ul class="stat-list alternate-list item-list">
|
||||||
|
{{#each characters as |character id|}}
|
||||||
|
<li class="item flexrow " data-actor-id="{{character.id}}" >
|
||||||
|
<img class="item-name-img" src="{{character.img}}" />
|
||||||
|
<span class="item-name-label competence-name">{{character.name}}</span>
|
||||||
|
<div class="item-filler"> </div>
|
||||||
|
<div class="item-controls item-controls-fixed">
|
||||||
|
<a class="item-control actor-edit" title="Edit Actor"><i class="fas fa-edit"></i></a>
|
||||||
|
<a class="item-control actor-delete" title="Delete Actor"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3>{{localize "ECRY.ui.location"}}</h3>
|
||||||
|
<ul class="stat-list alternate-list item-list">
|
||||||
|
{{#each system.base.location as |location index|}}
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-medium">
|
||||||
|
{{localize "ECRY.ui.location"}} {{index}}
|
||||||
|
</span>
|
||||||
|
<textarea class="textarea-default" rows="3" name="system.base.location.{{index}}">{{location}}</textarea>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-medium">
|
||||||
|
{{localize "ECRY.ui.enhancements"}}
|
||||||
|
</span>
|
||||||
|
<textarea class="textarea-default" rows="3" name="system.base.enhancements">{{system.base.enhancements}}</textarea>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if hasBoheme}}
|
||||||
|
<div class="tab boheme" data-group="primary" data-tab="boheme">
|
||||||
|
|
||||||
|
<h3>{{localize "ECRY.ui.oniricform"}}</h3>
|
||||||
|
<ul class="stat-list alternate-list item-list">
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-medium">{{localize "ECRY.ui.name"}}</span>
|
||||||
|
<input type="text" class="item-field-label-long" name="system.boheme.name" value="{{system.boheme.name}}" data-dtype="String"/>
|
||||||
|
</li>
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-medium">{{localize "ECRY.ui.ideals"}}</span>
|
||||||
|
<input type="text" class="item-field-label-long" name="system.boheme.ideals" value="{{system.boheme.ideals}}" data-dtype="String"/>
|
||||||
|
</li>
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-medium">{{localize "ECRY.ui.politic"}}</span>
|
||||||
|
<input type="text" class="item-field-label-long" name="system.boheme.politic" value="{{system.boheme.politic}}" data-dtype="String"/>
|
||||||
|
</li>
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<span class="item-name-label-medium">{{localize "ECRY.ui.description"}}</span>
|
||||||
|
<textarea class="textarea-default" rows="3" name="system.boheme.description">{{system.boheme.description}}</textarea>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</form>
|
6
templates/actors/editor-notes-gm.hbs
Normal file
6
templates/actors/editor-notes-gm.hbs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{{#if data.isGM}}
|
||||||
|
<h3>GM Notes : </h3>
|
||||||
|
<div class="form-group editor">
|
||||||
|
{{editor data.gmnotes target="system.gmnotes" button=true owner=owner editable=editable}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
17
templates/actors/partial-impacts.hbs
Normal file
17
templates/actors/partial-impacts.hbs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<div class="impact-box">
|
||||||
|
|
||||||
|
<div class="impact-title">
|
||||||
|
<label class="items-title-text">{{localize (concat "ECRY.ui.impact" impacttype)}} ({{impactMalus}})</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{{#each impacts as |value key|}}
|
||||||
|
<li class="flexrow" data-impact-type="{{../impacttype}}">
|
||||||
|
<span class="item-field-label-medium"><label>{{localize (concat "ECRY.ui." key)}}</label></span>
|
||||||
|
<a class="impact-modify" data-impact-modifier="+1" data-impact-type="{{../impacttype}}" data-impact-level="{{key}}"><i class="fas fa-plus-square"></i></a>
|
||||||
|
<span class="">{{value}}</span>
|
||||||
|
<a class="impact-modify" data-impact-modifier="-1" data-impact-type="{{../impacttype}}" data-impact-level="{{key}}"><i class="fas fa-minus-square"></i></a>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
37
templates/chat/chat-cephaly-result.hbs
Normal file
37
templates/chat/chat-cephaly-result.hbs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<div class="chat-message-header">
|
||||||
|
{{#if actorImg}}
|
||||||
|
<img class="actor-icon" src="{{actorImg}}" alt="{{alias}}" />
|
||||||
|
{{/if}}
|
||||||
|
<h4 class="chat-actor-name">{{alias}}</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{{#if img}}
|
||||||
|
<div>
|
||||||
|
<img class="chat-icon" src="{{img}}" alt="{{alias}}" />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li>{{localize "ECRY.ui.cephaly"}} : {{localize skill.name}}</li>
|
||||||
|
|
||||||
|
{{#if annency}}
|
||||||
|
<li>{{localize "ECRY.ui.annencybonus"}} {{annency.name}}: {{annencyBonus}}</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (gt marginExecution 0)}}
|
||||||
|
<li>{{localize "ECRY.ui.execution"}} {{executionTotal}} vs {{difficulty}} : {{marginExecution}}</li>
|
||||||
|
<li>{{localize cephalySuccess}}</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (gt marginPreservation 0)}}
|
||||||
|
<li>{{localize "ECRY.ui.preservation"}} {{preservationTotal}} vs {{difficulty}} : {{marginPreservation}}</li>
|
||||||
|
<li>{{localize cephalyFailure}}</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
72
templates/chat/chat-confrontation-pending.hbs
Normal file
72
templates/chat/chat-confrontation-pending.hbs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<div class="chat-message-header">
|
||||||
|
{{#if actorImg}}
|
||||||
|
<img class="actor-icon" src="{{actorImg}}" alt="{{alias}}" />
|
||||||
|
{{/if}}
|
||||||
|
<h4 class="chat-actor-name">{{alias}}</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{{#if img}}
|
||||||
|
<div>
|
||||||
|
<img class="chat-icon" src="{{img}}" alt="{{alias}}" />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
{{#if (eq mode "cephaly")}}
|
||||||
|
<li>{{localize "ECRY.ui.cephaly"}} : {{localize skill.name}} </li>
|
||||||
|
{{else}}
|
||||||
|
<li>Confrontation : {{alias}} </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<li>{{localize skill.name}}: {{skill.value}} </li>
|
||||||
|
{{#if spec}}
|
||||||
|
<li>{{localize "ECRY.chat.specialization"}} {{spec.name}} (+{{spec.system.bonus}}) </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#each traitsBonus as |trait idx|}}
|
||||||
|
{{#if trait.activated}}
|
||||||
|
<li>{{localize "ECRY.chat.traitbonus"}}: {{trait.name}} ({{trait.system.level}}) </li>
|
||||||
|
{{/if}}
|
||||||
|
{{/each}}
|
||||||
|
{{#each traitsMalus as |trait idx|}}
|
||||||
|
{{#if trait.activated}}
|
||||||
|
<li>{{localize "ECRY.chat.traitmalus"}}: {{trait.name}} ({{trait.system.level}}) </li>
|
||||||
|
{{/if}}
|
||||||
|
{{/each}}
|
||||||
|
{{#if bonusMalusTraits}}
|
||||||
|
<li>{{localize "ECRY.chat.bonusmalustraits"}}: {{bonusMalusTraits}} </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (isGM)}}
|
||||||
|
{{else}}
|
||||||
|
<li>{{localize "ECRY.ui.execution"}} : {{executionTotal}}</li>
|
||||||
|
<li>{{localize "ECRY.ui.preservation"}} : {{preservationTotal}}</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{#if (isGM)}}
|
||||||
|
{{#if (eq mode "cephaly")}}
|
||||||
|
<div>
|
||||||
|
<span>{{localize "ECRY.chat.difficulty"}}</span>
|
||||||
|
<select id="{{rollId}}-cephaly-difficulty" name="cephaly-difficulty">
|
||||||
|
{{#for 1 20 1}}
|
||||||
|
<option value="{{this}}">{{this}}</option>
|
||||||
|
{{/for}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button class="button-apply-cephaly-difficulty">{{localize "ECRY.ui.cephalydifficulty"}}</button>
|
||||||
|
{{else}}
|
||||||
|
<button class="button-select-confront">{{localize "ECRY.ui.selectconfront"}}</button>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
<div>
|
||||||
|
{{localize "ECRY.chat.sentogm"}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
54
templates/chat/chat-confrontation-result.hbs
Normal file
54
templates/chat/chat-confrontation-result.hbs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<div class="chat-message-header">
|
||||||
|
{{#if actorImg}}
|
||||||
|
<img class="actor-icon" src="{{actorImg}}" alt="{{alias}}" />
|
||||||
|
{{/if}}
|
||||||
|
<h4 class="chat-actor-name">{{alias}}</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{{#if img}}
|
||||||
|
<div>
|
||||||
|
<img class="chat-icon" src="{{img}}" alt="{{alias}}" />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li>Confrontation : {{rollData1.alias}} vs {{rollData2.alias}}</li>
|
||||||
|
<li>{{localize rollData1.skill.name}} ({{rollData1.skill.value}}) vs {{localize rollData2.skill.name}} ({{rollData2.skill.value}}) </li>
|
||||||
|
<li>{{rollData1.executionTotal}} vs {{rollData2.preservationTotal}} : {{marginExecution}}</li>
|
||||||
|
<li>{{rollData1.preservationTotal}} vs {{rollData2.executionTotal}} : {{marginPreservation}}</li>
|
||||||
|
|
||||||
|
{{#if rollData1.weapon}}
|
||||||
|
<li>{{rollData1.alias}} {{rollData1.weapon.name}} ({{rollData1.weapon.system.effect}})
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if rollData2.weapon}}
|
||||||
|
<li>{{rollData2.alias}} {{rollData2.weapon.name}} ({{rollData2.weapon.system.effect}})</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<li>{{localize "ECRY.ui.effect"}} {{localize "ECRY.ui.execution"}} : {{effectExecution}}</li>
|
||||||
|
{{#if impactExecution}}
|
||||||
|
<li>Impact {{rollData2.alias}} : 1 {{localize (concat "ECRY.ui." impactExecution)}}</li>
|
||||||
|
<button class="button-apply-impact" data-actor-id="{{rollData2.actorId}}" data-impact-type={{rollData1.skill.categKey}} data-impact="{{impactExecution}}">{{localize "ECRY.ui.applyimpact"}}</button>
|
||||||
|
{{/if}}
|
||||||
|
{{#if bonus2}}
|
||||||
|
<li>Bonus {{rollData2.alias}} : {{bonus2}}</li>
|
||||||
|
<button class="button-apply-bonus" data-actor-id="{{rollData2.actorId}}" data-bonus="{{bonus2}}">{{localize "ECRY.ui.applybonus"}}</button>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<li>{{localize "ECRY.ui.effect"}} {{localize "ECRY.ui.preservation"}} : {{effectPreservation}}</li>
|
||||||
|
{{#if impactPreservation}}
|
||||||
|
<li>Impact {{rollData1.alias}} : 1 {{localize (concat "ECRY.ui." impactPreservation)}}</li>
|
||||||
|
<button class="button-apply-impact" data-actor-id="{{rollData1.actorId}}" data-impact-type={{rollData1.skill.categKey}} data-impact="{{impactPreservation}}">{{localize "ECRY.ui.applyimpact"}}</button>
|
||||||
|
{{/if}}
|
||||||
|
{{#if bonus1}}
|
||||||
|
<li>Bonus {{rollData1.alias}} : {{bonus1}}</li>
|
||||||
|
<button class="button-apply-bonus" data-actor-id="{{rollData1.actorId}}" data-bonus="{{bonus1}}">{{localize "ECRY.ui.applybonus"}}</button>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
65
templates/chat/chat-generic-result.hbs
Normal file
65
templates/chat/chat-generic-result.hbs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<div class="chat-message-header">
|
||||||
|
{{#if actorImg}}
|
||||||
|
<img class="actor-icon" src="{{actorImg}}" alt="{{alias}}" />
|
||||||
|
{{/if}}
|
||||||
|
<h4 class="chat-actor-name">{{alias}}</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{{#if img}}
|
||||||
|
<div >
|
||||||
|
<img class="chat-icon" src="{{img}}" alt="{{name}}" />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="flexcol">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
{{#if skill}}
|
||||||
|
<li>{{localize skill.name}}: {{skill.value}} </li>
|
||||||
|
{{#if spec}}
|
||||||
|
<li>{{localize "ECRY.chat.specialization"}} {{spec.name}} (+{{spec.system.bonus}}) </li>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if impactMalus}}
|
||||||
|
<li>{{localize "ECRY.ui.impactmalus"}}: {{impactMalus}} </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if skillTranscendence}}
|
||||||
|
<li>{{localize "ECRY.ui.skilltranscendence"}}: {{skillTranscendence}} </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if traitsBonusList}}
|
||||||
|
{{#each traitsBonusList as |trait idx|}}
|
||||||
|
<li>{{localize "ECRY.chat.traitbonus"}}: {{trait.name}} ({{trait.system.level}}) </li>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if traitsMalusList}}
|
||||||
|
{{#each traitsMalusList as |trait idx|}}
|
||||||
|
<li>{{localize "ECRY.chat.traitmalus"}}: {{trait.name}} ({{trait.system.level}}) </li>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if bonusMalusTraits}}
|
||||||
|
<li>{{localize "ECRY.chat.bonusmalustraits"}}: {{bonusMalusTraits}} </li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<li>{{localize "ECRY.chat.formula"}}: {{diceFormula}} </li>
|
||||||
|
<li>{{localize "ECRY.chat.dicesum"}}: {{diceSum}} </li>
|
||||||
|
<li>{{localize "ECRY.chat.result"}}: {{total}} </li>
|
||||||
|
{{#if difficulty}}
|
||||||
|
<li>{{localize "ECRY.chat.difficulty"}}: {{difficulty}} - {{localize "ECRY.chat.margin"}}: {{margin}} </li>
|
||||||
|
{{#if isSuccess}}
|
||||||
|
<li><label class="chat-result-text chat-result-success ">{{localize "ECRY.chat.success"}}</label></li>
|
||||||
|
{{else}}
|
||||||
|
<li><label class="chat-result-text chat-result-failure">{{localize "ECRY.chat.failure"}}</label></li>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
86
templates/dialogs/character-summary.hbs
Normal file
86
templates/dialogs/character-summary.hbs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<form class="{{cssClass}} flexcol character-summary-container" autocomplete="off">
|
||||||
|
|
||||||
|
<ol class="items-list">
|
||||||
|
|
||||||
|
<li class="item flexrow item-header">
|
||||||
|
<div class="item-field item-name item-name-label-long">Nom</div>
|
||||||
|
{{#each config.attributs as |attr key|}}
|
||||||
|
<div class="item-field item-name-label-short">{{attr}}</div>
|
||||||
|
{{/each}}
|
||||||
|
<div class="item-field item-name-label-short">Destin</div>
|
||||||
|
<div class="item-field item-name-label-short">Fluide</div>
|
||||||
|
<div class="item-field item-name-label-short">MPMB</div>
|
||||||
|
<div class="item-field item-name-label-short">MPMN</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{{#each pcs as |pc key|}}
|
||||||
|
<li class="item flexrow" data-actor-id="{{pc.id}}">
|
||||||
|
<div class="item-field item-name item-name-label-long">
|
||||||
|
<a class="actor-open character-summary-rollable">{{pc.name}}</a>
|
||||||
|
</div>
|
||||||
|
{{#each pc.system.attributs as |attr key|}}
|
||||||
|
<div class="item-field flex2 item-name-label-short">
|
||||||
|
<a class="summary-roll character-summary-rollable" data-type="attribut" data-key="{{key}}">{{attr.value}}</a>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
<div class="item-field flex item-name-label-short">
|
||||||
|
<a class="summary-roll" data-type="destin" data-key="pointdestin">{{pc.system.pointdestin}}</a>
|
||||||
|
</div>
|
||||||
|
<div class="item-field flex item-name-label-short">
|
||||||
|
<a class="summary-roll" data-type="fluide" data-key="fluide">{{pc.system.fluide}}</a>
|
||||||
|
</div>
|
||||||
|
<div class="item-field flex item-name-label-short">
|
||||||
|
<a class="summary-roll" data-type="mpmb" data-key="mpmb">{{pc.system.mpmb}}</a>
|
||||||
|
</div>
|
||||||
|
<div class="item-field flex item-name-label-short">
|
||||||
|
<a class="summary-roll" data-type="mpmn" data-key="mpmn">{{pc.system.mpmn}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
<li class="item flexrow item-header">
|
||||||
|
<div class="item-field item-name item-name-label-long">PNJs</div>
|
||||||
|
{{#each config.attributs as |attr key|}}
|
||||||
|
<div class="item-field flex2 item-name-label-short">attr</div>
|
||||||
|
{{/each}}
|
||||||
|
<div class="item-field flex2 item-name-label-short">Destin</div>
|
||||||
|
<div class="item-field flex2 item-name-label-short">Fluide</div>
|
||||||
|
<div class="item-field flex2 item-name-label-short">MPMB</div>
|
||||||
|
<div class="item-field flex2 item-name-label-short">MPMN</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{{#each npcs as |pc key|}}
|
||||||
|
<li class="item flexrow" data-actor-id="{{pc.id}}">
|
||||||
|
<div class="item-field item-name item-name-label-long">
|
||||||
|
<a class="actor-open character-summary-rollable">{{pc.name}}</a>
|
||||||
|
</div>
|
||||||
|
{{#each pc.system.attributs as |attr key|}}
|
||||||
|
<div class="item-field flex2 item-name-label-short">
|
||||||
|
<a class="summary-roll character-summary-rollable" data-type="attribute" data-key="{{key}}">{{attr.value}}</a>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
<div class="item-field flex item-name-label-short">
|
||||||
|
<a class="summary-roll" data-type="destin" data-key="pointdestin">{{pc.system.pointdestin}}</a>
|
||||||
|
</div>
|
||||||
|
<div class="item-field flex item-name-label-short">
|
||||||
|
<a class="summary-roll" data-type="fluide" data-key="fluide">{{pc.system.fluide}}</a>
|
||||||
|
</div>
|
||||||
|
<div class="item-field flex item-name-label-short">
|
||||||
|
<a class="summary-roll" data-type="mpmb" data-key="mpmb">{{pc.system.mpmb}}</a>
|
||||||
|
</div>
|
||||||
|
<div class="item-field flex item-name-label-short">
|
||||||
|
<a class="summary-roll" data-type="mpmn" data-key="mpmn">{{pc.system.mpmn}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-field flex1 right">
|
||||||
|
<a class="item-control actor-delete" title="{{localize "BOL.ui.delete"}}"><i class="fas fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
</form>
|
140
templates/dialogs/confront-dialog.hbs
Normal file
140
templates/dialogs/confront-dialog.hbs
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<form class="confrontation-roll-dialog">
|
||||||
|
<header class="roll-dialog-header">
|
||||||
|
{{#if img}}
|
||||||
|
<img class="actor-icon" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||||
|
{{/if}}
|
||||||
|
<h1 class="dialog-roll-title roll-dialog-header">{{title}} ({{skill.value}})</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="flexcol">
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3>{{localize "ECRY.ui.execution"}} : <span id="execution-total">{{executionTotal}}</span> </h3>
|
||||||
|
<div id="confront-execution" class="flexrow confront-area confront-execution-area">
|
||||||
|
{{> systems/fvtt-ecryme/templates/dialogs/partial-confront-dice-area.hbs filter="execution"}}
|
||||||
|
{{> systems/fvtt-ecryme/templates/dialogs/partial-confront-bonus-area.hbs filter="execution"}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3>{{localize "ECRY.ui.preservation"}} : <span id="preservation-total">{{preservationTotal}}</span></h3>
|
||||||
|
<div id="confront-preservation" class="flexrow confront-area confront-preservation-area">
|
||||||
|
{{> systems/fvtt-ecryme/templates/dialogs/partial-confront-dice-area.hbs filter="preservation"}}
|
||||||
|
{{> systems/fvtt-ecryme/templates/dialogs/partial-confront-bonus-area.hbs filter="preservation"}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>{{localize "ECRY.ui.dicepool"}}</h4>
|
||||||
|
<div id="confront-dice-pool" class="flexrow confront-area confrontation-dice-list pool-list">
|
||||||
|
{{> systems/fvtt-ecryme/templates/dialogs/partial-confront-dice-area.hbs filter="mainpool"}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>{{localize "ECRY.ui.bonuspool"}} (Total : {{count confrontBonus}})</h4>
|
||||||
|
<div id="confront-bonus-pool" class="flexrow confront-area confrontation-bonus-list pool-list">
|
||||||
|
{{> systems/fvtt-ecryme/templates/dialogs/partial-confront-bonus-area.hbs filter="mainpool"}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if weapon}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.weapon"}} : </span>
|
||||||
|
<span class="roll-dialog-label">{{weapon.name}} ({{localize "ECRY.ui.effect"}} {{weapon.system.effect}})</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if impactMalus}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.impactmalus"}} : </span>
|
||||||
|
<span class="roll-dialog-label">{{impactMalus}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.skilltranscendence"}} : </span>
|
||||||
|
<select class="" id="roll-select-transcendence" data-type="Number">
|
||||||
|
{{#select skillTranscendence}}
|
||||||
|
{{#for 0 skill.value 1}}
|
||||||
|
<option value="{{this}}">{{this}}</option>
|
||||||
|
{{/for}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.transcendapply"}} : </span>
|
||||||
|
<select class="" id="roll-apply-transcendence" data-type="String">
|
||||||
|
{{#select applyTranscendence}}
|
||||||
|
<option value="execution">{{localize "ECRY.ui.execution"}}</option>
|
||||||
|
<option value="preservation">{{localize "ECRY.ui.preservation"}}</option>
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if skill.spec}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.spec"}} : </span>
|
||||||
|
<select class="" id="roll-specialization" data-type="String" multiple>
|
||||||
|
{{#each skill.spec as |spec idx|}}
|
||||||
|
<option value="{{spec.id}}" {{#if (eq spec.name @root.spec.name)}}selected{{/if}}>{{spec.name}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.traitbonus"}} : </span>
|
||||||
|
<select class="" id="roll-trait-bonus" data-type="String" multiple>
|
||||||
|
{{#each traitsBonus as |trait idx|}}
|
||||||
|
<option value="{{trait._id}}" {{#if trait.activated}}selected{{/if}}>{{trait.name}} ({{trait.system.level}})</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.traitmalus"}} : </span>
|
||||||
|
<select class="" id="roll-trait-malus" data-type="String" multiple>
|
||||||
|
{{#each traitsMalus as |trait idx|}}
|
||||||
|
<option value="{{trait._id}}" {{#if trait.activated}}selected{{/if}}>{{trait.name}} ({{trait.system.level}})</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if annency}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.annency"}} : {{annency.name}}</span>
|
||||||
|
<span class="roll-dialog-label">{{annency.system.base.description}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.annencybonus"}}</span>
|
||||||
|
<select class="" id="annency-bonus" name="annencyBonus" data-type="String">
|
||||||
|
<option value="0">0</option>
|
||||||
|
<option value="1">+1</option>
|
||||||
|
<option value="2">+2</option>
|
||||||
|
<option value="3">+3</option>
|
||||||
|
<option value="4">+4</option>
|
||||||
|
<option value="5">+5</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Bonus/Malus : </span>
|
||||||
|
<select id="bonusMalusPerso" name="bonusMalusPerso">
|
||||||
|
{{#select bonusMalusPerso}}
|
||||||
|
<option value="-3">-3</option>
|
||||||
|
<option value="-2">-2</option>
|
||||||
|
<option value="-1">-1</option>
|
||||||
|
<option value="0">0</option>
|
||||||
|
<option value="1">+1</option>
|
||||||
|
<option value="2">+2</option>
|
||||||
|
<option value="3">+3</option>
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
13
templates/dialogs/confront-start-dialog.hbs
Normal file
13
templates/dialogs/confront-start-dialog.hbs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<form class="confrontation-roll-dialog">
|
||||||
|
<header class="roll-dialog-header">
|
||||||
|
{{#if img}}
|
||||||
|
<img class="actor-icon" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||||
|
{{/if}}
|
||||||
|
<h1 class="dialog-roll-title roll-dialog-header">{{title}}</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="flexcol">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
90
templates/dialogs/partial-common-roll-dialog.hbs
Normal file
90
templates/dialogs/partial-common-roll-dialog.hbs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
{{#if skill}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize skill.name}} : </span>
|
||||||
|
<span class="roll-dialog-label">{{skill.value}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if impactMalus}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.impactmalus"}} : </span>
|
||||||
|
<span class="roll-dialog-label">{{impactMalus}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.skilltranscendence"}} : </span>
|
||||||
|
<select class="" id="roll-select-transcendence" data-type="Number">
|
||||||
|
{{#select skillTranscendence}}
|
||||||
|
{{#for 0 skill.value 1}}
|
||||||
|
<option value="{{this}}">{{this}}</option>
|
||||||
|
{{/for}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if forcedSpec}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.spec"}} : </span>
|
||||||
|
<span class="roll-dialog-label">{{forcedSpec.name}} (+{{forcedSpec.system.bonus}})</span>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.spec"}} : </span>
|
||||||
|
<select class="" id="roll-specialization" data-type="String" multiple>
|
||||||
|
{{#each skill.spec as |spec idx|}}
|
||||||
|
<option value="{{spec.id}}">{{spec.name}} (+{{spec.system.bonus}})</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if spleen}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.applyspleen"}} {{spleen.name}}</span>
|
||||||
|
<input type="checkbox" class="item-field-label-short" id="roll-use-spleen" {{checked useSpleen}} />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if ideal}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.applyideal"}} {{ideal.name}}</span>
|
||||||
|
<input type="checkbox" class="item-field-label-short" id="roll-use-ideal" {{checked useIdeal}} />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.traitbonus"}} : </span>
|
||||||
|
<select class="" id="roll-trait-bonus" data-type="String" multiple>
|
||||||
|
{{#each traits as | trait idx|}}
|
||||||
|
<option value="{{trait._id}}">{{trait.name}} ({{trait.system.level}})</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">{{localize "ECRY.ui.traitmalus"}} : </span>
|
||||||
|
<select class="" id="roll-trait-malus" data-type="String" multiple>
|
||||||
|
{{#each traits as | trait idx|}}
|
||||||
|
<option value="{{trait._id}}">{{trait.name}} ({{trait.system.level}})</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Bonus/Malus : </span>
|
||||||
|
<select id="bonusMalusPerso" name="bonusMalusPerso">
|
||||||
|
{{#select bonusMalusPerso}}
|
||||||
|
<option value="-3">-3</option>
|
||||||
|
<option value="-2">-2</option>
|
||||||
|
<option value="-1">-1</option>
|
||||||
|
<option value="0">0</option>
|
||||||
|
<option value="1">+1</option>
|
||||||
|
<option value="2">+2</option>
|
||||||
|
<option value="3">+3</option>
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
10
templates/dialogs/partial-confront-bonus-area.hbs
Normal file
10
templates/dialogs/partial-confront-bonus-area.hbs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{{#each confrontBonus as |bonus idx|}}
|
||||||
|
{{#if (eq bonus.location ../filter)}}
|
||||||
|
<div class="confront-dice-container bonus-spec" data-drag-type="bonus" data-bonus-idx={{idx}}>
|
||||||
|
<span draggable="true" data-drag-type="bonus" data-bonus-idx={{idx}}>
|
||||||
|
<img class="confront-dice" data-drag-type="bonus" data-bonus-idx={{idx}} src="icons/svg/circle.svg" >
|
||||||
|
<label class="confront-bonus-centered" data-drag-type="bonus" data-bonus-idx={{idx}}>+1</label>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/each}}
|
11
templates/dialogs/partial-confront-dice-area.hbs
Normal file
11
templates/dialogs/partial-confront-dice-area.hbs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{{#each availableDices as |dice idx|}}
|
||||||
|
{{#if (eq dice.location ../filter)}}
|
||||||
|
<div class="confront-dice-container dice-spec" data-drag-type="dice" data-dice-idx={{idx}} data-dice-value="{{dice.result}}">
|
||||||
|
<span draggable="true" data-drag-type="dice" data-dice-idx={{idx}} data-dice-value="{{dice.result}}">
|
||||||
|
<img class="confront-dice" src="icons/svg/d6-grey.svg" data-drag-type="dice" data-dice-idx={{idx}} data-dice-value="{{dice.result}}">
|
||||||
|
<label class="confront-dice-centered" data-drag-type="dice" data-dice-idx={{idx}}
|
||||||
|
data-dice-value="{{dice.result}}">{{dice.result}}</label>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/each}}
|
27
templates/dialogs/roll-dialog-generic.hbs
Normal file
27
templates/dialogs/roll-dialog-generic.hbs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<form class="skill-roll-dialog">
|
||||||
|
<header class="roll-dialog-header">
|
||||||
|
{{#if img}}
|
||||||
|
<img class="actor-icon" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||||
|
{{/if}}
|
||||||
|
<h1 class="dialog-roll-title roll-dialog-header">{{title}}</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="flexcol">
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/dialogs/partial-common-roll-dialog.hbs}}
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Difficulté : </span>
|
||||||
|
<select class="" type="text" id="roll-difficulty" value="{{difficulty}}" data-dtype="Number">
|
||||||
|
{{#select difficulty}}
|
||||||
|
{{#each config.difficulty as |diffData value| }}
|
||||||
|
<option value="{{diffData.value}}">{{localize diffData.difficulty}} / {{localize diffData.frequency}}
|
||||||
|
({{diffData.value}})</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
27
templates/items/item-elementbio-sheet.hbs
Normal file
27
templates/items/item-elementbio-sheet.hbs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
<header class="sheet-header">
|
||||||
|
<img class="item-sheet-img" src="{{img}}" data-edit="img" title="{{name}}"/>
|
||||||
|
<div class="header-fields">
|
||||||
|
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name"/></h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-nav.hbs}}
|
||||||
|
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-description.hbs}}
|
||||||
|
|
||||||
|
<div class="tab details" data-group="primary" data-tab="details">
|
||||||
|
|
||||||
|
<div class="tab" data-group="primary">
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</form>
|
25
templates/items/item-equipment-sheet.hbs
Normal file
25
templates/items/item-equipment-sheet.hbs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
<header class="sheet-header">
|
||||||
|
<img class="item-sheet-img" src="{{img}}" data-edit="img" title="{{name}}"/>
|
||||||
|
<div class="header-fields">
|
||||||
|
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name"/></h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-nav.hbs}}
|
||||||
|
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-description.hbs}}
|
||||||
|
|
||||||
|
<div class="tab details" data-group="primary" data-tab="details">
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-equipment.hbs}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</form>
|
48
templates/items/item-impact-sheet.hbs
Normal file
48
templates/items/item-impact-sheet.hbs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
<header class="sheet-header">
|
||||||
|
<img class="item-sheet-img" src="{{img}}" data-edit="img" title="{{name}}"/>
|
||||||
|
<div class="header-fields">
|
||||||
|
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name"/></h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-nav.hbs}}
|
||||||
|
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-description.hbs}}
|
||||||
|
|
||||||
|
<div class="tab details" data-group="primary" data-tab="details">
|
||||||
|
|
||||||
|
<div class="tab" data-group="primary">
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-name-label-long">{{localize "ECRY.ui.impactType"}}</label>
|
||||||
|
<select class="item-field-label-medium" type="text" name="system.impacttype" value="{{system.impacttype}}" data-dtype="String">
|
||||||
|
{{#select system.impacttype}}
|
||||||
|
{{#each config.impactTypes as |type key| }}
|
||||||
|
<option value="{{key}}">{{localize type}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-name-label-long">{{localize "ECRY.ui.impactLevel"}}</label>
|
||||||
|
<select class="item-field-label-medium" type="text" name="system.impactlevel" value="{{system.impactlevel}}" data-dtype="String">
|
||||||
|
{{#select system.impactlevel}}
|
||||||
|
{{#each config.impactLevels as |level key| }}
|
||||||
|
<option value="{{key}}">{{localize level}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</form>
|
27
templates/items/item-maneuver-sheet.hbs
Normal file
27
templates/items/item-maneuver-sheet.hbs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
<header class="sheet-header">
|
||||||
|
<img class="item-sheet-img" src="{{img}}" data-edit="img" title="{{name}}"/>
|
||||||
|
<div class="header-fields">
|
||||||
|
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name"/></h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-nav.hbs}}
|
||||||
|
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-description.hbs}}
|
||||||
|
|
||||||
|
<div class="tab details" data-group="primary" data-tab="details">
|
||||||
|
|
||||||
|
<div class="tab" data-group="primary">
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</form>
|
43
templates/items/item-specialization-sheet.hbs
Normal file
43
templates/items/item-specialization-sheet.hbs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
<header class="sheet-header">
|
||||||
|
<img class="item-sheet-img" src="{{img}}" data-edit="img" title="{{name}}"/>
|
||||||
|
<div class="header-fields">
|
||||||
|
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name"/></h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-nav.hbs}}
|
||||||
|
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-description.hbs}}
|
||||||
|
|
||||||
|
<div class="tab details" data-group="primary" data-tab="details">
|
||||||
|
|
||||||
|
<div class="tab" data-group="primary">
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-name-label-long">{{localize "ECRY.ui.skill"}}</label>
|
||||||
|
<select class="item-field-label-medium" type="text" name="system.skillkey" value="{{system.skillkey}}" data-dtype="String">
|
||||||
|
{{#select system.skillkey}}
|
||||||
|
{{#each config.skills as |skill key| }}
|
||||||
|
<option value="{{key}}">{{localize skill.name}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-name-label-long">{{localize "ECRY.ui.bonus"}}</label>
|
||||||
|
<input type="text" class="item-field-label-short" name="system.bonus" value="{{system.bonus}}" data-dtype="Number"/>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</form>
|
48
templates/items/item-trait-sheet.hbs
Normal file
48
templates/items/item-trait-sheet.hbs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
<header class="sheet-header">
|
||||||
|
<img class="item-sheet-img" src="{{img}}" data-edit="img" title="{{name}}"/>
|
||||||
|
<div class="header-fields">
|
||||||
|
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name"/></h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-nav.hbs}}
|
||||||
|
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-description.hbs}}
|
||||||
|
|
||||||
|
<div class="tab details" data-group="primary" data-tab="details">
|
||||||
|
|
||||||
|
<div class="tab" data-group="primary">
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-name-label-long">{{localize "ECRY.ui.traitType"}}</label>
|
||||||
|
<select class="item-field-label-medium" type="text" name="system.traitype" value="{{system.traitype}}" data-dtype="String">
|
||||||
|
{{#select system.traitype}}
|
||||||
|
{{#each config.traitTypes as |type key| }}
|
||||||
|
<option value="{{key}}">{{type}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-name-label-long">{{localize "ECRY.ui.niveauTrait"}}</label>
|
||||||
|
<select class="item-field-label-medium" type="text" name="system.level" value="{{system.level}}" data-dtype="Number">
|
||||||
|
{{#select system.level}}
|
||||||
|
{{#each config.traitLevel as |level key| }}
|
||||||
|
<option value="{{level.value}}">{{level.text}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</form>
|
45
templates/items/item-weapon-sheet.hbs
Normal file
45
templates/items/item-weapon-sheet.hbs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
<header class="sheet-header">
|
||||||
|
<img class="item-sheet-img" src="{{img}}" data-edit="img" title="{{name}}"/>
|
||||||
|
<div class="header-fields">
|
||||||
|
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name"/></h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-nav.hbs}}
|
||||||
|
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-description.hbs}}
|
||||||
|
|
||||||
|
<div class="tab details" data-group="primary" data-tab="details">
|
||||||
|
|
||||||
|
<div class="tab" data-group="primary">
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-name-label-long">{{localize "ECRY.ui.weapontype"}}</label>
|
||||||
|
<select class="item-field-label-medium" type="text" name="system.weapontype" value="{{system.weapontype}}" data-dtype="String">
|
||||||
|
{{#select system.weapontype}}
|
||||||
|
{{#each config.weaponTypes as |type key| }}
|
||||||
|
<option value="{{key}}">{{localize type}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-name-label-long">{{localize "ECRY.ui.effect"}}</label>
|
||||||
|
<input type="text" class="item-field-label-short" name="system.effect" value="{{system.effect}}" data-dtype="Number"/>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{{> systems/fvtt-ecryme/templates/items/partial-item-equipment.hbs}}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</form>
|
3
templates/items/partial-item-description.hbs
Normal file
3
templates/items/partial-item-description.hbs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div class="tab description" data-group="primary" data-tab="description">
|
||||||
|
{{editor description target="system.description" button=true owner=owner editable=editable}}
|
||||||
|
</div>
|
18
templates/items/partial-item-equipment.hbs
Normal file
18
templates/items/partial-item-equipment.hbs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-field-label-long">{{localize "ECRY.ui.weight"}}</label>
|
||||||
|
<input type="text" class="item-field-label-short" name="system.weight" value="{{system.weight}}"
|
||||||
|
data-dtype="Number" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="flexrow">
|
||||||
|
<label class="item-field-label-long">{{localize "ECRY.ui.cost"}}</label>
|
||||||
|
<input type="text" class="item-field-label-short" name="system.cost" value="{{system.cost}}" data-dtype="Number" />
|
||||||
|
<select class="item-field-label-medium" type="text" name="system.costunit" value="{{system.costunit}}" data-dtype="String">
|
||||||
|
{{#select system.costunit}}
|
||||||
|
{{#each config.costUnits as |unit key| }}
|
||||||
|
<option value="{{key}}">{{localize unit.name}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
|
5
templates/items/partial-item-nav.hbs
Normal file
5
templates/items/partial-item-nav.hbs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{{!-- Sheet Tab Navigation --}}
|
||||||
|
<nav class="sheet-tabs tabs" data-group="primary">
|
||||||
|
<a class="item" data-tab="description">Description</a>
|
||||||
|
<a class="item" data-tab="details">Details</a>
|
||||||
|
</nav>
|
Loading…
x
Reference in New Issue
Block a user