forked from public/bol
Add fight options
This commit is contained in:
parent
eacd32927c
commit
02b3dd5e0f
11
css/bol.css
11
css/bol.css
@ -617,6 +617,14 @@ a:hover {
|
|||||||
color: darkred;
|
color: darkred;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
h2.good {
|
||||||
|
color: darkgreen;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
h2.bad {
|
||||||
|
color: darkred;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
.message-header h2.roll {
|
.message-header h2.roll {
|
||||||
color: darkslategrey;
|
color: darkslategrey;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -935,3 +943,6 @@ body.system-bol img#logo {
|
|||||||
width: 64px;
|
width: 64px;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
}
|
}
|
||||||
|
.dialog-button {
|
||||||
|
max-height: 2rem;
|
||||||
|
}
|
21
lang/en.json
21
lang/en.json
@ -140,6 +140,14 @@
|
|||||||
"BOL.ui.rangeModifiers": "Range modifier",
|
"BOL.ui.rangeModifiers": "Range modifier",
|
||||||
"BOL.ui.money": "Bougette",
|
"BOL.ui.money": "Bougette",
|
||||||
"BOL.ui.moneyTitle": "Gold & Treasure",
|
"BOL.ui.moneyTitle": "Gold & Treasure",
|
||||||
|
"BOL.ui.fightOption": "Fight Options",
|
||||||
|
"BOL.ui.none": "None",
|
||||||
|
"BOL.ui.fightOptionType": "Fight Options types",
|
||||||
|
"BOL.ui.activated": "Activated",
|
||||||
|
"BOL.ui.deactivated": "Deactivated",
|
||||||
|
"BOL.ui.status": "Status",
|
||||||
|
"BOL.ui.toactivated": "Active (>Désactiver)",
|
||||||
|
"BOL.ui.todeactivated": "Inactive (>Activer)",
|
||||||
|
|
||||||
"BOL.featureCategory.origins": "Origines",
|
"BOL.featureCategory.origins": "Origines",
|
||||||
"BOL.featureCategory.races": "Races",
|
"BOL.featureCategory.races": "Races",
|
||||||
@ -147,6 +155,7 @@
|
|||||||
"BOL.featureCategory.boons": "Avantages",
|
"BOL.featureCategory.boons": "Avantages",
|
||||||
"BOL.featureCategory.flaws": "Désavantages",
|
"BOL.featureCategory.flaws": "Désavantages",
|
||||||
"BOL.featureCategory.languages": "Langages",
|
"BOL.featureCategory.languages": "Langages",
|
||||||
|
"BOL.featureCategory.fightoptions": "Fight Options",
|
||||||
|
|
||||||
"BOL.featureSubtypes.origin": "Origine",
|
"BOL.featureSubtypes.origin": "Origine",
|
||||||
"BOL.featureSubtypes.race": "Race",
|
"BOL.featureSubtypes.race": "Race",
|
||||||
@ -155,13 +164,22 @@
|
|||||||
"BOL.featureSubtypes.flaw": "Désavantage",
|
"BOL.featureSubtypes.flaw": "Désavantage",
|
||||||
"BOL.featureSubtypes.language": "Langage",
|
"BOL.featureSubtypes.language": "Langage",
|
||||||
"BOL.featureSubtypes.gods": "Faith & Gods",
|
"BOL.featureSubtypes.gods": "Faith & Gods",
|
||||||
|
"BOL.featureSubtypes.fightOption": "Combat Option",
|
||||||
|
|
||||||
"BOL.bougette.nomoney": "Nothing",
|
"BOL.bougette.nomoney": "Nothing",
|
||||||
"BOL.bougette.tolive": "To live",
|
"BOL.bougette.tolive": "To live",
|
||||||
"BOL.bougette.easylife": "Easy Life",
|
"BOL.bougette.easylife": "Easy Life",
|
||||||
"BOL.bougette.luxury" : "Luxury life",
|
"BOL.bougette.luxury" : "Luxury life",
|
||||||
"BOL.bougette.rich": "Rich!",
|
"BOL.bougette.rich": "Rich!",
|
||||||
|
|
||||||
|
"BOL.fightOptionTypes.armor": "Attaque au défaut d'armure",
|
||||||
|
"BOL.fightOptionTypes.intrepid": "Attaque intrépide",
|
||||||
|
"BOL.fightOptionTypes.twoweaponsdef": "Combat à 2 armes (Défense)",
|
||||||
|
"BOL.fightOptionTypes.twoweaponsatt": "Combat à 2 armes (Attaque)",
|
||||||
|
"BOL.fightOptionTypes.fulldefense": "Défense totale",
|
||||||
|
"BOL.fightOptionTypes.defense": "Posture défensive",
|
||||||
|
"BOL.fightOptionTypes.attack": "Posture offensive",
|
||||||
|
|
||||||
"BOL.itemCategory.object": "Objet",
|
"BOL.itemCategory.object": "Objet",
|
||||||
"BOL.itemCategory.equipment": "Équipement",
|
"BOL.itemCategory.equipment": "Équipement",
|
||||||
"BOL.itemCategory.consumable": "Consommable",
|
"BOL.itemCategory.consumable": "Consommable",
|
||||||
@ -175,6 +193,7 @@
|
|||||||
"BOL.combatCategory.shields": "Boucliers",
|
"BOL.combatCategory.shields": "Boucliers",
|
||||||
"BOL.combatCategory.melee": "Armes de contact",
|
"BOL.combatCategory.melee": "Armes de contact",
|
||||||
"BOL.combatCategory.ranged": "Armes à distance",
|
"BOL.combatCategory.ranged": "Armes à distance",
|
||||||
|
"BOL.combatCategory.fightOptions": "Fight options",
|
||||||
|
|
||||||
"BOL.equipmentCategory.weapon": "Arme",
|
"BOL.equipmentCategory.weapon": "Arme",
|
||||||
"BOL.equipmentCategory.armor": "Armure",
|
"BOL.equipmentCategory.armor": "Armure",
|
||||||
|
23
lang/fr.json
23
lang/fr.json
@ -142,6 +142,14 @@
|
|||||||
"BOL.ui.rangeModifiers": "Mod. de Portée",
|
"BOL.ui.rangeModifiers": "Mod. de Portée",
|
||||||
"BOL.ui.money": "Bougette",
|
"BOL.ui.money": "Bougette",
|
||||||
"BOL.ui.moneyTitle": "Or et Piecettes",
|
"BOL.ui.moneyTitle": "Or et Piecettes",
|
||||||
|
"BOL.ui.fightOption": "Options de Combat",
|
||||||
|
"BOL.ui.none": "Aucune",
|
||||||
|
"BOL.ui.fightOptionType": "Types d'options de Combat",
|
||||||
|
"BOL.ui.activated": "Active",
|
||||||
|
"BOL.ui.deactivated": "Inactive",
|
||||||
|
"BOL.ui.toactivated": "Active (>Désactiver)",
|
||||||
|
"BOL.ui.todeactivated": "Inactive (>Activer)",
|
||||||
|
"BOL.ui.status": "Statut",
|
||||||
|
|
||||||
"BOL.featureCategory.origins": "Origines",
|
"BOL.featureCategory.origins": "Origines",
|
||||||
"BOL.featureCategory.races": "Races",
|
"BOL.featureCategory.races": "Races",
|
||||||
@ -149,7 +157,8 @@
|
|||||||
"BOL.featureCategory.boons": "Avantages",
|
"BOL.featureCategory.boons": "Avantages",
|
||||||
"BOL.featureCategory.flaws": "Désavantages",
|
"BOL.featureCategory.flaws": "Désavantages",
|
||||||
"BOL.featureCategory.languages": "Langues",
|
"BOL.featureCategory.languages": "Langues",
|
||||||
|
"BOL.featureCategory.fightoptions": "Options de Combat",
|
||||||
|
|
||||||
"BOL.bougette.nomoney": "A sec",
|
"BOL.bougette.nomoney": "A sec",
|
||||||
"BOL.bougette.tolive": "De quoi vivre",
|
"BOL.bougette.tolive": "De quoi vivre",
|
||||||
"BOL.bougette.easylife": "A l'aise",
|
"BOL.bougette.easylife": "A l'aise",
|
||||||
@ -163,6 +172,15 @@
|
|||||||
"BOL.featureSubtypes.flaw": "Désavantage",
|
"BOL.featureSubtypes.flaw": "Désavantage",
|
||||||
"BOL.featureSubtypes.language": "Langue",
|
"BOL.featureSubtypes.language": "Langue",
|
||||||
"BOL.featureSubtypes.gods": "Dieux & Foi",
|
"BOL.featureSubtypes.gods": "Dieux & Foi",
|
||||||
|
"BOL.featureSubtypes.fightOption": "Option de Combat",
|
||||||
|
|
||||||
|
"BOL.fightOptionTypes.armor": "Attaque au défaut d'armure",
|
||||||
|
"BOL.fightOptionTypes.intrepid": "Attaque intrépide",
|
||||||
|
"BOL.fightOptionTypes.twoweaponsdef": "Combat à 2 armes (Défense)",
|
||||||
|
"BOL.fightOptionTypes.twoweaponsatt": "Combat à 2 armes (Attaque)",
|
||||||
|
"BOL.fightOptionTypes.fulldefense": "Défense totale",
|
||||||
|
"BOL.fightOptionTypes.defense": "Posture défensive",
|
||||||
|
"BOL.fightOptionTypes.attack": "Posture offensive",
|
||||||
|
|
||||||
"BOL.itemCategory.object": "Objet",
|
"BOL.itemCategory.object": "Objet",
|
||||||
"BOL.itemCategory.equipment": "Équipement",
|
"BOL.itemCategory.equipment": "Équipement",
|
||||||
@ -177,7 +195,8 @@
|
|||||||
"BOL.combatCategory.shields": "Boucliers",
|
"BOL.combatCategory.shields": "Boucliers",
|
||||||
"BOL.combatCategory.melee": "Armes de contact",
|
"BOL.combatCategory.melee": "Armes de contact",
|
||||||
"BOL.combatCategory.ranged": "Armes à distance",
|
"BOL.combatCategory.ranged": "Armes à distance",
|
||||||
|
"BOL.combatCategory.fightOptions": "Options de combat",
|
||||||
|
|
||||||
"BOL.equipmentCategory.weapon": "Arme",
|
"BOL.equipmentCategory.weapon": "Arme",
|
||||||
"BOL.equipmentCategory.armor": "Armure",
|
"BOL.equipmentCategory.armor": "Armure",
|
||||||
"BOL.equipmentCategory.protection": "Protection",
|
"BOL.equipmentCategory.protection": "Protection",
|
||||||
|
@ -42,7 +42,12 @@ export class BoLActorSheet extends ActorSheet {
|
|||||||
html.find('.create_item').click(ev => {
|
html.find('.create_item').click(ev => {
|
||||||
this.actor.createEmbeddedDocuments('Item', [{ name: "Nouvel Equipement", type: "item" }], { renderSheet: true });
|
this.actor.createEmbeddedDocuments('Item', [{ name: "Nouvel Equipement", type: "item" }], { renderSheet: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
html.find(".toggle-fight-option").click((ev) => {
|
||||||
|
const li = $(ev.currentTarget).parents(".item")
|
||||||
|
this.actor.toggleFightOption( li.data("itemId") )
|
||||||
|
})
|
||||||
|
|
||||||
html.find(".inc-dec-btns-alchemy").click((ev) => {
|
html.find(".inc-dec-btns-alchemy").click((ev) => {
|
||||||
const li = $(ev.currentTarget).parents(".item");
|
const li = $(ev.currentTarget).parents(".item");
|
||||||
this.actor.spendAlchemyPoint( li.data("itemId"), 1)
|
this.actor.spendAlchemyPoint( li.data("itemId"), 1)
|
||||||
@ -97,17 +102,6 @@ export class BoLActorSheet extends ActorSheet {
|
|||||||
// Rollable abilities.
|
// Rollable abilities.
|
||||||
html.find('.rollable').click(this._onRoll.bind(this));
|
html.find('.rollable').click(this._onRoll.bind(this));
|
||||||
|
|
||||||
// html.find('.roll-attribute').click(ev => {
|
|
||||||
// this.actor.rollAttributeAptitude( $(ev.currentTarget).data("attr-key") );
|
|
||||||
// });
|
|
||||||
// html.find('.roll-career').click(ev => {
|
|
||||||
// const li = $(ev.currentTarget).parents(".item");
|
|
||||||
// this.actor.rollCareer( li.data("itemId") );
|
|
||||||
// });
|
|
||||||
// html.find('.roll-weapon').click(ev => {
|
|
||||||
// const li = $(ev.currentTarget).parents(".item");
|
|
||||||
// this.actor.rollWeapon( li.data("itemId") );
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -131,11 +125,11 @@ export class BoLActorSheet extends ActorSheet {
|
|||||||
formData.alchemy = this.actor.alchemy
|
formData.alchemy = this.actor.alchemy
|
||||||
formData.containers = this.actor.containers
|
formData.containers = this.actor.containers
|
||||||
formData.treasure = this.actor.treasure
|
formData.treasure = this.actor.treasure
|
||||||
formData.treasure = this.actor.treasure
|
formData.alchemyrecipe = this.actor.alchemyrecipe
|
||||||
formData.treasure = this.actor.alchemyrecipe
|
formData.vehicles = this.actor.vehicles
|
||||||
formData.vehicles = this.actor.vehicles;
|
formData.fightoptions = this.actor.fightoptions
|
||||||
formData.ammos = this.actor.ammos;
|
formData.ammos = this.actor.ammos
|
||||||
formData.misc = this.actor.misc;
|
formData.misc = this.actor.misc
|
||||||
formData.combat = this.actor.buildCombat()
|
formData.combat = this.actor.buildCombat()
|
||||||
formData.features = this.actor.buildFeatures()
|
formData.features = this.actor.buildFeatures()
|
||||||
formData.isGM = game.user.isGM
|
formData.isGM = game.user.isGM
|
||||||
@ -148,9 +142,9 @@ export class BoLActorSheet extends ActorSheet {
|
|||||||
formData.isAlchemist = this.actor.isAlchemist()
|
formData.isAlchemist = this.actor.isAlchemist()
|
||||||
formData.isPriest = this.actor.isPriest()
|
formData.isPriest = this.actor.isPriest()
|
||||||
|
|
||||||
formData.isGM= game.user.isGM
|
formData.isGM = game.user.isGM
|
||||||
|
|
||||||
console.log("ACTORDATA", formData);
|
console.log("ACTORDATA", formData)
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -22,11 +22,6 @@ export class BoLActor extends Actor {
|
|||||||
super.prepareData();
|
super.prepareData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
//_onUpdate(changed, options, user) {
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
updateResourcesData( ) {
|
updateResourcesData( ) {
|
||||||
if ( this.type == 'character') {
|
if ( this.type == 'character') {
|
||||||
@ -50,22 +45,92 @@ export class BoLActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
get itemData(){
|
get itemData(){
|
||||||
return Array.from(this.data.items.values()).map(i => i.data);
|
return Array.from(this.data.items.values()).map(i => i.data)
|
||||||
}
|
}
|
||||||
get details() {
|
get details() {
|
||||||
return this.data.data.details;
|
return this.data.data.details
|
||||||
}
|
}
|
||||||
get attributes() {
|
get attributes() {
|
||||||
return Object.values(this.data.data.attributes);
|
return Object.values(this.data.data.attributes)
|
||||||
}
|
}
|
||||||
get aptitudes() {
|
get aptitudes() {
|
||||||
return Object.values(this.data.data.aptitudes);
|
return Object.values(this.data.data.aptitudes)
|
||||||
}
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
get defenseValue() {
|
get defenseValue() {
|
||||||
return this.data.data.aptitudes.def.value;
|
let defMod = 0
|
||||||
|
let fo = this.getActiveFightOption()
|
||||||
|
if (fo && fo.data.properties.fightoptiontype == "intrepid" ) {
|
||||||
|
defMod += -2
|
||||||
|
}
|
||||||
|
if (fo && fo.data.properties.fightoptiontype == "fulldefense" ) {
|
||||||
|
defMod += 2
|
||||||
|
}
|
||||||
|
if (fo && fo.data.properties.fightoptiontype == "twoweaponsdef" && !fo.data.properties.used) {
|
||||||
|
defMod += 1
|
||||||
|
this.updateEmbeddedDocuments("Item", [ {_id: fo._id, 'data.properties.used': true}] )
|
||||||
|
}
|
||||||
|
if (fo && fo.data.properties.fightoptiontype == "defense" ) {
|
||||||
|
defMod += 1
|
||||||
|
}
|
||||||
|
if (fo && fo.data.properties.fightoptiontype == "attack" ) {
|
||||||
|
defMod += -1
|
||||||
|
}
|
||||||
|
return this.data.data.aptitudes.def.value + defMod
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getActiveFightOption( ) {
|
||||||
|
let it = this.itemData.find(i => i.type === "feature" && i.data.subtype === "fightoption" && i.data.properties.activated)
|
||||||
|
if (it) {
|
||||||
|
return duplicate(it)
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async toggleFightOption( itemId) {
|
||||||
|
let fightOption = this.data.items.get(itemId)
|
||||||
|
let state
|
||||||
|
let updates = []
|
||||||
|
|
||||||
|
if ( fightOption) {
|
||||||
|
fightOption = duplicate(fightOption)
|
||||||
|
if (fightOption.data.properties.activated) {
|
||||||
|
state = false
|
||||||
|
} else {
|
||||||
|
state = true
|
||||||
|
}
|
||||||
|
updates.push( {_id: fightOption._id, 'data.properties.activated': state} ) // Update the selected one
|
||||||
|
await this.updateEmbeddedDocuments("Item", updates) // Apply all changes
|
||||||
|
// Then notify
|
||||||
|
ChatMessage.create({
|
||||||
|
alias: this.name,
|
||||||
|
whisper: BoLUtility.getWhisperRecipientsAndGMs(this.name),
|
||||||
|
content: await renderTemplate('systems/bol/templates/chat/chat-activate-fight-option.hbs', { name: this.name, img: fightOption.img, foName: fightOption.name, state: state} )
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
get armorMalusValue() { // used for Fight Options
|
||||||
|
for(let armor of this.armors) {
|
||||||
|
if (armor.data.properties.armorQuality.includes("light")) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (armor.data.properties.armorQuality.includes("medium")) {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if (armor.data.properties.armorQuality.includes("heavy")) {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
get resources() {
|
get resources() {
|
||||||
return Object.values(this.data.data.resources);
|
return Object.values(this.data.data.resources)
|
||||||
}
|
}
|
||||||
get boons() {
|
get boons() {
|
||||||
return this.itemData.filter(i => i.type === "feature" && i.data.subtype === "boon");
|
return this.itemData.filter(i => i.type === "feature" && i.data.subtype === "boon");
|
||||||
@ -83,13 +148,16 @@ export class BoLActor extends Actor {
|
|||||||
return this.itemData.filter(i => i.type === "feature" && i.data.subtype === "race");
|
return this.itemData.filter(i => i.type === "feature" && i.data.subtype === "race");
|
||||||
}
|
}
|
||||||
get languages() {
|
get languages() {
|
||||||
return this.itemData.filter(i => i.type === "feature" && i.data.subtype === "language");
|
return this.itemData.filter(i => i.type === "feature" && i.data.subtype === "language")
|
||||||
|
}
|
||||||
|
get fightoptions() {
|
||||||
|
return this.itemData.filter(i => i.type === "feature" && i.data.subtype === "fightoption")
|
||||||
}
|
}
|
||||||
get features() {
|
get features() {
|
||||||
return this.itemData.filter(i => i.type === "feature");
|
return this.itemData.filter(i => i.type === "feature")
|
||||||
}
|
}
|
||||||
get equipment() {
|
get equipment() {
|
||||||
return this.itemData.filter(i => i.type === "item");
|
return this.itemData.filter(i => i.type === "item")
|
||||||
}
|
}
|
||||||
get armors() {
|
get armors() {
|
||||||
return this.itemData.filter(i => i.type === "item" && i.data.category === "equipment" && i.data.subtype === "armor");
|
return this.itemData.filter(i => i.type === "item" && i.data.category === "equipment" && i.data.subtype === "armor");
|
||||||
@ -100,7 +168,7 @@ export class BoLActor extends Actor {
|
|||||||
get shields() {
|
get shields() {
|
||||||
return this.itemData.filter(i => i.type === "item" && i.data.category === "equipment" && i.data.subtype === "shield");
|
return this.itemData.filter(i => i.type === "item" && i.data.category === "equipment" && i.data.subtype === "shield");
|
||||||
}
|
}
|
||||||
|
|
||||||
get weapons() {
|
get weapons() {
|
||||||
return this.itemData.filter(i => i.type === "item" && i.data.category === "equipment" && i.data.subtype === "weapon");
|
return this.itemData.filter(i => i.type === "item" && i.data.category === "equipment" && i.data.subtype === "weapon");
|
||||||
}
|
}
|
||||||
@ -267,9 +335,15 @@ export class BoLActor extends Actor {
|
|||||||
"label": "BOL.featureCategory.languages",
|
"label": "BOL.featureCategory.languages",
|
||||||
"ranked": false,
|
"ranked": false,
|
||||||
"items": this.languages
|
"items": this.languages
|
||||||
|
},
|
||||||
|
"fightoptions": {
|
||||||
|
"label": "BOL.featureCategory.fightoptions",
|
||||||
|
"ranked": false,
|
||||||
|
"items": this.fightoptions
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildCombat(){
|
buildCombat(){
|
||||||
return {
|
return {
|
||||||
"melee" : {
|
"melee" : {
|
||||||
@ -278,6 +352,7 @@ export class BoLActor extends Actor {
|
|||||||
"protection" : false,
|
"protection" : false,
|
||||||
"blocking" : false,
|
"blocking" : false,
|
||||||
"ranged" : false,
|
"ranged" : false,
|
||||||
|
"options": false,
|
||||||
"items" : this.melee
|
"items" : this.melee
|
||||||
},
|
},
|
||||||
"ranged" : {
|
"ranged" : {
|
||||||
@ -286,6 +361,7 @@ export class BoLActor extends Actor {
|
|||||||
"protection" : false,
|
"protection" : false,
|
||||||
"blocking" : false,
|
"blocking" : false,
|
||||||
"ranged" : true,
|
"ranged" : true,
|
||||||
|
"options": false,
|
||||||
"items" : this.ranged
|
"items" : this.ranged
|
||||||
},
|
},
|
||||||
"protections" : {
|
"protections" : {
|
||||||
@ -294,6 +370,7 @@ export class BoLActor extends Actor {
|
|||||||
"protection" : true,
|
"protection" : true,
|
||||||
"blocking" : false,
|
"blocking" : false,
|
||||||
"ranged" : false,
|
"ranged" : false,
|
||||||
|
"options": false,
|
||||||
"items" : this.protections
|
"items" : this.protections
|
||||||
},
|
},
|
||||||
"shields" : {
|
"shields" : {
|
||||||
@ -302,9 +379,19 @@ export class BoLActor extends Actor {
|
|||||||
"protection" : false,
|
"protection" : false,
|
||||||
"blocking" : true,
|
"blocking" : true,
|
||||||
"ranged" : false,
|
"ranged" : false,
|
||||||
|
"options": false,
|
||||||
"items" : this.shields
|
"items" : this.shields
|
||||||
|
},
|
||||||
|
"fightoptions" : {
|
||||||
|
"label" : "BOL.combatCategory.fightOptions",
|
||||||
|
"weapon" : false,
|
||||||
|
"protection" : false,
|
||||||
|
"blocking" : false,
|
||||||
|
"ranged" : false,
|
||||||
|
"options": true,
|
||||||
|
"items" : this.fightoptions
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------- */
|
/*-------------------------------------------- */
|
||||||
|
@ -3,39 +3,47 @@ import { BoLUtility } from "../system/bol-utility.js";
|
|||||||
const __adv2dice = { ["1B"]: 3, ["2B"]: 4, ["2"]: 2, ["1M"]: 3, ["2M"]: 4 }
|
const __adv2dice = { ["1B"]: 3, ["2B"]: 4, ["2"]: 2, ["1M"]: 3, ["2M"]: 4 }
|
||||||
const _apt2attr = { init: "mind", melee: "agility", ranged: "agility", def: "vigor" }
|
const _apt2attr = { init: "mind", melee: "agility", ranged: "agility", def: "vigor" }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
export class BoLRoll {
|
export class BoLRoll {
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
static options() {
|
static options() {
|
||||||
return { classes: ["bol", "dialog"], width: 480, height: 540 };
|
return { classes: ["bol", "dialog"], width: 480, height: 540 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
static convertToAdv(adv) {
|
static convertToAdv(adv) {
|
||||||
if (adv == 0) return "2"
|
if (adv == 0) return "2"
|
||||||
return Math.abs(adv) + (adv < 0) ? 'M' : 'B';
|
return Math.abs(adv) + (adv < 0) ? 'M' : 'B';
|
||||||
}
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
static getDefaultAttribute(key) {
|
static getDefaultAttribute(key) {
|
||||||
return _apt2attr[key]
|
return _apt2attr[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static attributeCheck(actor, actorData, dataset, event) {
|
static attributeCheck(actor, actorData, dataset, event) {
|
||||||
const key = dataset.key;
|
const key = dataset.key
|
||||||
const adv = dataset.adv;
|
const adv = dataset.adv
|
||||||
let attribute = eval(`actor.data.data.attributes.${key}`);
|
|
||||||
let label = (attribute.label) ? game.i18n.localize(attribute.label) : null;
|
let attribute = eval(`actor.data.data.attributes.${key}`)
|
||||||
let description = actor.name + " - " + game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label);
|
let label = (attribute.label) ? game.i18n.localize(attribute.label) : null
|
||||||
return this.displayRollDialog(
|
let description = actor.name + " - " + game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label)
|
||||||
{
|
|
||||||
mode: "attribute",
|
let rollData = {
|
||||||
actor: actor,
|
mode: "attribute",
|
||||||
actorData: actorData,
|
actor: actor,
|
||||||
attribute: attribute,
|
actorData: actorData,
|
||||||
attrValue: attribute.value,
|
attribute: attribute,
|
||||||
aptValue: 0,
|
attrValue: attribute.value,
|
||||||
label: label,
|
aptValue: 0,
|
||||||
careerBonus: 0,
|
label: label,
|
||||||
description: description,
|
careerBonus: 0,
|
||||||
adv: this.convertToAdv(adv),
|
description: description,
|
||||||
mod: 0
|
adv: this.convertToAdv(adv),
|
||||||
});
|
mod: 0
|
||||||
|
}
|
||||||
|
return this.displayRollDialog( rollData )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -69,24 +77,31 @@ export class BoLRoll {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static weaponCheck(actor, actorData, dataset, event) {
|
static weaponCheck(actor, actorData, dataset, event) {
|
||||||
let target = BoLUtility.getTarget()
|
let target = BoLUtility.getTarget()
|
||||||
const li = $(event.currentTarget).parents(".item");
|
const li = $(event.currentTarget).parents(".item")
|
||||||
const weapon = actor.items.get(li.data("item-id"));
|
const weapon = actor.items.get(li.data("item-id"))
|
||||||
if (!weapon) {
|
if (!weapon) {
|
||||||
ui.notifications.warn("Unable to find weapon !");
|
ui.notifications.warn("Unable to find weapon !")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let weaponData = weapon.data.data
|
let weaponData = weapon.data.data
|
||||||
let attribute = eval(`actor.data.data.attributes.${weaponData.properties.attackAttribute}`)
|
let attribute = eval(`actor.data.data.attributes.${weaponData.properties.attackAttribute}`)
|
||||||
let aptitude = eval(`actor.data.data.aptitudes.${weaponData.properties.attackAptitude}`)
|
let aptitude = eval(`actor.data.data.aptitudes.${weaponData.properties.attackAptitude}`)
|
||||||
|
|
||||||
console.debug("WEAPON!", weaponData)
|
// Manage specific case
|
||||||
let attackDef = {
|
let fightOption= actor.getActiveFightOption()
|
||||||
|
if ( fightOption && fightOption.data.fightoptiontype == "fulldefense") {
|
||||||
|
ui.notifications.warn(`{{actor.name}} est en Défense Totale ! Il ne peut pas attaquer ce round.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Build the roll structure
|
||||||
|
let rolldata = {
|
||||||
mode: "weapon",
|
mode: "weapon",
|
||||||
actor: actor,
|
actor: actor,
|
||||||
actorData: actorData,
|
actorData: actorData,
|
||||||
weapon: weapon,
|
weapon: weapon,
|
||||||
isRanged: weaponData.properties.ranged || weaponData.properties.throwing,
|
isRanged: weaponData.properties.ranged || weaponData.properties.throwing,
|
||||||
target: target,
|
target: target,
|
||||||
|
fightOption: fightOption,
|
||||||
careerBonus: 0,
|
careerBonus: 0,
|
||||||
defender: (target) ? game.actors.get(target.data.actorId) : undefined,
|
defender: (target) ? game.actors.get(target.data.actorId) : undefined,
|
||||||
attribute: attribute,
|
attribute: attribute,
|
||||||
@ -98,7 +113,7 @@ export class BoLRoll {
|
|||||||
label: (weapon.name) ? weapon.name : game.i18n.localize('BOL.ui.noWeaponName'),
|
label: (weapon.name) ? weapon.name : game.i18n.localize('BOL.ui.noWeaponName'),
|
||||||
description: actor.name + " - " + game.i18n.localize('BOL.ui.weaponAttack'),
|
description: actor.name + " - " + game.i18n.localize('BOL.ui.weaponAttack'),
|
||||||
}
|
}
|
||||||
return this.displayRollDialog(attackDef);
|
return this.displayRollDialog(rolldata)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -179,7 +194,36 @@ export class BoLRoll {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$('#roll-modifier').val( this.rollData.attrValue + "+" + this.rollData.aptValue + "+" + this.rollData.careerBonus + "+" + this.rollData.mod + "+" +
|
$('#roll-modifier').val( this.rollData.attrValue + "+" + this.rollData.aptValue + "+" + this.rollData.careerBonus + "+" + this.rollData.mod + "+" +
|
||||||
this.rollData.modRanged + "+" + this.rollData.weaponModifier + "-" + this.rollData.defence + "+" + this.rollData.shieldMalus )
|
this.rollData.modRanged + "+" + this.rollData.weaponModifier + "-" + this.rollData.defence + "-" + this.rollData.modArmorMalus + "-" +
|
||||||
|
this.rollData.shieldMalus + "+" + this.rollData.attackModifier )
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static preProcessFightOption( rollData) {
|
||||||
|
rollData.damagesIgnoresArmor = false // Always reset flags
|
||||||
|
rollData.modArmorMalus = 0
|
||||||
|
rollData.attackModifier = 0
|
||||||
|
|
||||||
|
let fgItem = rollData.fightOption
|
||||||
|
if (fgItem ) {
|
||||||
|
console.log(fgItem)
|
||||||
|
if (fgItem.data.properties.fightoptiontype == "armordefault") {
|
||||||
|
rollData.modArmorMalus = rollData.armorMalus // Activate the armor malus
|
||||||
|
rollData.damagesIgnoresArmor = true
|
||||||
|
}
|
||||||
|
if (fgItem.data.properties.fightoptiontype == "intrepid") {
|
||||||
|
rollData.attackModifier += 2
|
||||||
|
}
|
||||||
|
if (fgItem.data.properties.fightoptiontype == "defense") {
|
||||||
|
rollData.attackModifier += -1
|
||||||
|
}
|
||||||
|
if (fgItem.data.properties.fightoptiontype == "attack") {
|
||||||
|
rollData.attackModifier += 1
|
||||||
|
}
|
||||||
|
if (fgItem.data.properties.fightoptiontype == "twoweaponsdef" || fgItem.data.properties.fightoptiontype == "twoweaponsatt") {
|
||||||
|
rollData.attackModifier += -1
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -250,15 +294,37 @@ export class BoLRoll {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static preProcessWeapon( rollData) {
|
||||||
|
if (rollData.mode == "weapon") {
|
||||||
|
rollData.weaponModifier = rollData.weapon.data.data.properties.attackModifiers ?? 0;
|
||||||
|
rollData.attackBonusDice = rollData.weapon.data.data.properties.attackBonusDice
|
||||||
|
if (rollData.defender) { // If target is selected
|
||||||
|
rollData.defence = rollData.defender.defenseValue
|
||||||
|
rollData.armorMalus = rollData.defender.armorMalusValue
|
||||||
|
rollData.shieldBlock = 'none'
|
||||||
|
let shields = rollData.defender.shields
|
||||||
|
for (let shield of shields) {
|
||||||
|
rollData.shieldBlock = (shield.data.properties.blocking.blockingAll) ? 'blockall' : 'blockone';
|
||||||
|
rollData.shieldAttackMalus = (shield.data.properties.blocking.malus) ? shield.data.properties.blocking.malus : 1;
|
||||||
|
rollData.applyShieldMalus = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ROLL DIALOGS */
|
/* ROLL DIALOGS */
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async displayRollDialog(rollData, onEnter = "submit") {
|
static async displayRollDialog(rollData, onEnter = "submit") {
|
||||||
|
|
||||||
|
// initialize default flags/values
|
||||||
const rollOptionTpl = `systems/bol/templates/dialogs/${rollData.mode}-roll-dialog.hbs`
|
const rollOptionTpl = `systems/bol/templates/dialogs/${rollData.mode}-roll-dialog.hbs`
|
||||||
rollData.careers = rollData.actorData.features.careers
|
rollData.careers = rollData.actorData.features.careers
|
||||||
rollData.boons = rollData.actor.bonusBoons
|
rollData.boons = rollData.actor.bonusBoons
|
||||||
rollData.flaws = rollData.actor.malusFlaws
|
rollData.flaws = rollData.actor.malusFlaws
|
||||||
rollData.defence = 0
|
rollData.defence = 0
|
||||||
|
rollData.attackModifier = 0 // Used for fight options
|
||||||
|
rollData.modArmorMalus = 0 // Used for fight options
|
||||||
rollData.bDice = 0
|
rollData.bDice = 0
|
||||||
rollData.mDice = 0
|
rollData.mDice = 0
|
||||||
rollData.nbBoons = 0
|
rollData.nbBoons = 0
|
||||||
@ -273,31 +339,17 @@ export class BoLRoll {
|
|||||||
rollData.modRanged = rollData.modRanged ?? 0
|
rollData.modRanged = rollData.modRanged ?? 0
|
||||||
rollData.mod = rollData.mod ?? 0
|
rollData.mod = rollData.mod ?? 0
|
||||||
rollData.id = randomID(16)
|
rollData.id = randomID(16)
|
||||||
|
|
||||||
// Weapon mode specific management
|
|
||||||
rollData.weaponModifier = 0
|
rollData.weaponModifier = 0
|
||||||
rollData.attackBonusDice = false
|
rollData.attackBonusDice = false
|
||||||
|
rollData.armorMalus = 0
|
||||||
// Saves
|
// Specific stuff
|
||||||
|
this.preProcessWeapon(rollData)
|
||||||
|
this.preProcessFightOption(rollData)
|
||||||
|
// Save
|
||||||
this.rollData = rollData
|
this.rollData = rollData
|
||||||
console.log("ROLLDATA", rollData)
|
console.log("ROLLDATA", rollData)
|
||||||
|
|
||||||
if (rollData.mode == "weapon") {
|
// Then display+process the dialog
|
||||||
rollData.weaponModifier = rollData.weapon.data.data.properties.attackModifiers ?? 0;
|
|
||||||
rollData.attackBonusDice = rollData.weapon.data.data.properties.attackBonusDice
|
|
||||||
if (rollData.defender) { // If target is selected
|
|
||||||
rollData.defence = rollData.defender.defenseValue
|
|
||||||
rollData.shieldBlock = 'none'
|
|
||||||
let shields = rollData.defender.shields
|
|
||||||
//console.log("Shields", shields)
|
|
||||||
for (let shield of shields) {
|
|
||||||
rollData.shieldBlock = (shield.data.properties.blocking.blockingAll) ? 'blockall' : 'blockone';
|
|
||||||
rollData.shieldAttackMalus = (shield.data.properties.blocking.malus) ? shield.data.properties.blocking.malus : 1;
|
|
||||||
rollData.applyShieldMalus = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const rollOptionContent = await renderTemplate(rollOptionTpl, rollData);
|
const rollOptionContent = await renderTemplate(rollOptionTpl, rollData);
|
||||||
let d = new Dialog({
|
let d = new Dialog({
|
||||||
title: rollData.label,
|
title: rollData.label,
|
||||||
@ -325,7 +377,7 @@ export class BoLRoll {
|
|||||||
const isMalus = rollData.mDice > 0
|
const isMalus = rollData.mDice > 0
|
||||||
rollData.nbDice += (rollData.attackBonusDice) ? 1 : 0
|
rollData.nbDice += (rollData.attackBonusDice) ? 1 : 0
|
||||||
|
|
||||||
const modifiers = rollData.attrValue + rollData.aptValue + rollData.careerBonus + rollData.mod + rollData.weaponModifier - rollData.defence + rollData.shieldMalus
|
const modifiers = rollData.attrValue + rollData.aptValue + rollData.careerBonus + rollData.mod + rollData.weaponModifier - rollData.defence - rollData.modArmorMalus + rollData.shieldMalus + rollData.attackModifier
|
||||||
const formula = (isMalus) ? rollData.nbDice + "d6kl2 + " + modifiers : rollData.nbDice + "d6kh2 + " + modifiers
|
const formula = (isMalus) ? rollData.nbDice + "d6kl2 + " + modifiers : rollData.nbDice + "d6kh2 + " + modifiers
|
||||||
rollData.formula = formula
|
rollData.formula = formula
|
||||||
rollData.modifiers = modifiers
|
rollData.modifiers = modifiers
|
||||||
@ -365,15 +417,16 @@ export class BoLDefaultRoll {
|
|||||||
|
|
||||||
async roll() {
|
async roll() {
|
||||||
|
|
||||||
const r = new Roll(this.rollData.formula);
|
const r = new Roll(this.rollData.formula)
|
||||||
await r.roll({ "async": false });
|
// console.log("Roll formula", this.rollData.formula)
|
||||||
const activeDice = r.terms[0].results.filter(r => r.active);
|
await r.roll({ "async": false })
|
||||||
const diceTotal = activeDice.map(r => r.result).reduce((a, b) => a + b);
|
const activeDice = r.terms[0].results.filter(r => r.active)
|
||||||
|
const diceTotal = activeDice.map(r => r.result).reduce((a, b) => a + b)
|
||||||
this.rollData.roll = r
|
this.rollData.roll = r
|
||||||
this.rollData.isSuccess = (r.total >= 9);
|
this.rollData.isSuccess = (r.total >= 9)
|
||||||
this.rollData.isCritical = (diceTotal === 12)
|
this.rollData.isCritical = (diceTotal === 12)
|
||||||
this.rollData.isRealCritical = (diceTotal === 12)
|
this.rollData.isRealCritical = (diceTotal === 12)
|
||||||
this.rollData.isFumble = (diceTotal === 2);
|
this.rollData.isFumble = (diceTotal === 2)
|
||||||
this.rollData.isFailure = !this.rollData.isSuccess
|
this.rollData.isFailure = !this.rollData.isSuccess
|
||||||
if (this.rollData.reroll == undefined) {
|
if (this.rollData.reroll == undefined) {
|
||||||
this.rollData.reroll = this.rollData.actor.heroReroll()
|
this.rollData.reroll = this.rollData.actor.heroReroll()
|
||||||
@ -456,10 +509,10 @@ export class BoLDefaultRoll {
|
|||||||
bonusDmg = 12
|
bonusDmg = 12
|
||||||
}
|
}
|
||||||
let attrDamageValue = this.getDamageAttributeValue(this.rollData.weapon.data.data.properties.damageAttribute)
|
let attrDamageValue = this.getDamageAttributeValue(this.rollData.weapon.data.data.properties.damageAttribute)
|
||||||
let weaponFormula = BoLUtility.getDamageFormula(this.rollData.weapon.data.data)
|
let weaponFormula = BoLUtility.getDamageFormula(this.rollData.weapon.data.data, this.rollData.fightOption )
|
||||||
|
|
||||||
let damageFormula = weaponFormula + "+" + bonusDmg + "+" + attrDamageValue
|
let damageFormula = weaponFormula + "+" + bonusDmg + "+" + attrDamageValue
|
||||||
console.log("DAMAGE !!!", damageFormula, attrDamageValue)
|
console.log("DAMAGE !!!", damageFormula, attrDamageValue, this.rollData)
|
||||||
|
|
||||||
//console.log("Formula", weaponFormula, damageFormula, this.rollData.weapon.data.data.properties.damage)
|
//console.log("Formula", weaponFormula, damageFormula, this.rollData.weapon.data.data.properties.damage)
|
||||||
this.rollData.damageFormula = damageFormula
|
this.rollData.damageFormula = damageFormula
|
||||||
@ -474,7 +527,7 @@ export class BoLDefaultRoll {
|
|||||||
|
|
||||||
_buildDamageChatMessage(rollData) {
|
_buildDamageChatMessage(rollData) {
|
||||||
const rollMessageTpl = 'systems/bol/templates/chat/rolls/damage-roll-card.hbs';
|
const rollMessageTpl = 'systems/bol/templates/chat/rolls/damage-roll-card.hbs';
|
||||||
return renderTemplate(rollMessageTpl, rollData);
|
return renderTemplate(rollMessageTpl, rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildChatMessage(rollData) {
|
_buildChatMessage(rollData) {
|
||||||
|
@ -48,7 +48,18 @@ export class BoLCombatManager extends Combat {
|
|||||||
fvttInit += (cId / 100)
|
fvttInit += (cId / 100)
|
||||||
await this.updateEmbeddedDocuments("Combatant", [{ _id: ids[cId], initiative: fvttInit }]);
|
await this.updateEmbeddedDocuments("Combatant", [{ _id: ids[cId], initiative: fvttInit }]);
|
||||||
}
|
}
|
||||||
console.log("TODO : Compute init for actor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************/
|
||||||
|
nextRound() {
|
||||||
|
let combatants = this.combatants.contents
|
||||||
|
for (let c of combatants) {
|
||||||
|
let actor = game.actors.get( c.data.actorId )
|
||||||
|
//actor.clearRoundModifiers()
|
||||||
|
}
|
||||||
|
super.nextRound()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ export class BoLUtility {
|
|||||||
chatGM.whisper = this.getUsers(user => user.isGM);
|
chatGM.whisper = this.getUsers(user => user.isGM);
|
||||||
chatGM.content = "Blind message of " + game.user.name + "<br>" + chatOptions.content;
|
chatGM.content = "Blind message of " + game.user.name + "<br>" + chatOptions.content;
|
||||||
console.log("blindMessageToGM", chatGM);
|
console.log("blindMessageToGM", chatGM);
|
||||||
game.socket.emit("system.fvtt-fragged-kingdom", { msg: "msg_gm_chat_message", data: chatGM });
|
game.socket.emit("system.bol", { msg: "msg_gm_chat_message", data: chatGM });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -335,53 +335,6 @@ export class BoLUtility {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static async rollBoL(rollData) {
|
|
||||||
|
|
||||||
// Dice bonus/malus selection
|
|
||||||
let nbDice = 2;
|
|
||||||
let d6BM = 0;
|
|
||||||
let mode = "";
|
|
||||||
if (rollData.d6Malus > rollData.d6Bonus) {
|
|
||||||
d6BM = rollData.d6Malus - rollData.d6Bonus;
|
|
||||||
mode = "kl2";
|
|
||||||
}
|
|
||||||
if (rollData.d6Bonus > rollData.d6Malus) {
|
|
||||||
d6BM = rollData.d6Bonus - rollData.d6Malus;
|
|
||||||
mode = "kh2";
|
|
||||||
}
|
|
||||||
nbDice += d6BM;
|
|
||||||
|
|
||||||
// Final modifier
|
|
||||||
let modifier = Number(rollData.bonusMalus);
|
|
||||||
if (rollData.mode == 'career') {
|
|
||||||
modifier += Number(rollData.attributes[rollData.rollAttribute].value) + Number(rollData.career.data.rank);
|
|
||||||
} else if (rollData.mode == 'attribute') {
|
|
||||||
modifier += rollData.attribute.value;
|
|
||||||
} else if (rollData.mode == 'weapon') {
|
|
||||||
modifier += Number(rollData.attributes[rollData.rollAttribute].value) + Number(rollData.aptitude.value) + Number(rollData.rangeModifier);
|
|
||||||
modifier -= rollData.defender.data.aptitudes.def.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
let formula = nbDice + "d6" + mode + "+" + modifier;
|
|
||||||
|
|
||||||
console.log("Going to roll ", formula, rollData.attributes, rollData.rollAttribute);
|
|
||||||
let myRoll = new Roll(formula).roll({ async: false });
|
|
||||||
await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode"));
|
|
||||||
rollData.roll = myRoll;
|
|
||||||
rollData.formula = formula;
|
|
||||||
rollData.modifier = modifier;
|
|
||||||
rollData.nbDice = nbDice;
|
|
||||||
rollData.finalScore = myRoll.total;
|
|
||||||
|
|
||||||
let actor = game.actors.get(rollData.actorId);
|
|
||||||
actor.saveRollData(rollData);
|
|
||||||
|
|
||||||
this.createChatWithRollMode(rollData.alias, {
|
|
||||||
content: await renderTemplate(`systems/bol/templates/chat/chat-generic-result.hbs`, rollData)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async processAttackSuccess(attackDef) {
|
static async processAttackSuccess(attackDef) {
|
||||||
if (!game.user.isGM) { // Only GM process this
|
if (!game.user.isGM) { // Only GM process this
|
||||||
@ -399,9 +352,10 @@ export class BoLUtility {
|
|||||||
attacker: attackDef.attacker,
|
attacker: attackDef.attacker,
|
||||||
defender: attackDef.defender,
|
defender: attackDef.defender,
|
||||||
defenderWeapons: defenderWeapons,
|
defenderWeapons: defenderWeapons,
|
||||||
damageTotal: attackDef.damageRoll.total
|
damageTotal: attackDef.damageRoll.total,
|
||||||
|
damagesIgnoresArmor: attackDef.damagesIgnoresArmor,
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -423,7 +377,8 @@ export class BoLUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getDamageFormula(weaponData) {
|
static getDamageFormula(weaponData, fightOption) {
|
||||||
|
let upgradeDamage = (fightOption && fightOption.data.properties.fightoptiontype == "twoweaponsatt")
|
||||||
let damageString = weaponData.properties.damage
|
let damageString = weaponData.properties.damage
|
||||||
let modifier = weaponData.properties.damageModifiers ?? 0
|
let modifier = weaponData.properties.damageModifiers ?? 0
|
||||||
let multiplier = weaponData.properties.damageMultiplier ?? 1
|
let multiplier = weaponData.properties.damageMultiplier ?? 1
|
||||||
@ -435,26 +390,33 @@ export class BoLUtility {
|
|||||||
|
|
||||||
let formula = damageString
|
let formula = damageString
|
||||||
if (damageString.includes("d") || damageString.includes("D")) {
|
if (damageString.includes("d") || damageString.includes("D")) {
|
||||||
var myReg = new RegExp('(\\d+)[dD]([\\d]+)([MB]*)?([\\+\\d]*)?', 'g');
|
var myReg = new RegExp('(\\d+)[dD]([\\d]+)([MB]*)?([\\+\\d]*)?', 'g')
|
||||||
let res = myReg.exec(damageString);
|
let res = myReg.exec(damageString)
|
||||||
let nbDice = parseInt(res[1]);
|
let nbDice = parseInt(res[1])
|
||||||
let postForm = 'kh' + nbDice;
|
let postForm = 'kh' + nbDice
|
||||||
let modIndex = 3;
|
let modIndex = 3
|
||||||
|
// Upgrade damage if needed
|
||||||
|
if ( upgradeDamage && ( !res[3] || res[3]=="") ) {
|
||||||
|
res[3] = "B" // Upgrade to bonus
|
||||||
|
}
|
||||||
if (res[3]) {
|
if (res[3]) {
|
||||||
|
if ( upgradeDamage && res[3] == 'M') {
|
||||||
|
res[3] = "" // Disable lamlus for upgradeDamage
|
||||||
|
}
|
||||||
if (res[3] == 'M') {
|
if (res[3] == 'M') {
|
||||||
postForm = 'kl' + nbDice;
|
postForm = 'kl' + nbDice
|
||||||
nbDice++;
|
nbDice++
|
||||||
modIndex = 4;
|
modIndex = 4
|
||||||
}
|
}
|
||||||
if (res[3] == 'B') {
|
if (res[3] == 'B') {
|
||||||
postForm = 'kh' + nbDice;
|
postForm = 'kh' + nbDice
|
||||||
nbDice++;
|
nbDice++
|
||||||
modIndex = 4;
|
modIndex = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
formula = "(" + nbDice + "d" + res[2] + reroll + postForm + "+" + modifier + ") *" + multiplier;
|
formula = "(" + nbDice + "d" + res[2] + reroll + postForm + "+" + modifier + ") *" + multiplier
|
||||||
}
|
}
|
||||||
return formula;
|
return formula
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -254,7 +254,18 @@ BOL.featureSubtypes = {
|
|||||||
"boon" : "BOL.featureSubtypes.boon",
|
"boon" : "BOL.featureSubtypes.boon",
|
||||||
"flaw" : "BOL.featureSubtypes.flaw",
|
"flaw" : "BOL.featureSubtypes.flaw",
|
||||||
"language" : "BOL.featureSubtypes.language",
|
"language" : "BOL.featureSubtypes.language",
|
||||||
"godsfaith" : "BOL.featureSubtypes.gods"
|
"godsfaith" : "BOL.featureSubtypes.gods",
|
||||||
|
"fightoption" : "BOL.featureSubtypes.fightOption"
|
||||||
|
}
|
||||||
|
|
||||||
|
BOL.fightOptionTypes = {
|
||||||
|
"armordefault": "BOL.fightOptionTypes.armor",
|
||||||
|
"intrepid": "BOL.fightOptionTypes.intrepid",
|
||||||
|
"twoweaponsdef": "BOL.fightOptionTypes.twoweaponsdef",
|
||||||
|
"twoweaponsatt": "BOL.fightOptionTypes.twoweaponsatt",
|
||||||
|
"fulldefense": "BOL.fightOptionTypes.fulldefense",
|
||||||
|
"defense": "BOL.fightOptionTypes.defense",
|
||||||
|
"attack": "BOL.fightOptionTypes.attack",
|
||||||
}
|
}
|
||||||
|
|
||||||
BOL.itemIcons = {
|
BOL.itemIcons = {
|
||||||
|
@ -33,6 +33,7 @@ export const preloadHandlebarsTemplates = async function () {
|
|||||||
"systems/bol/templates/item/parts/properties/feature/flaw-properties.hbs",
|
"systems/bol/templates/item/parts/properties/feature/flaw-properties.hbs",
|
||||||
"systems/bol/templates/item/parts/properties/feature/origin-properties.hbs",
|
"systems/bol/templates/item/parts/properties/feature/origin-properties.hbs",
|
||||||
"systems/bol/templates/item/parts/properties/feature/race-properties.hbs",
|
"systems/bol/templates/item/parts/properties/feature/race-properties.hbs",
|
||||||
|
"systems/bol/templates/item/parts/properties/feature/fightoption-properties.hbs",
|
||||||
|
|
||||||
// DIALOGS
|
// DIALOGS
|
||||||
"systems/bol/templates/chat/rolls/attack-damage-card.hbs",
|
"systems/bol/templates/chat/rolls/attack-damage-card.hbs",
|
||||||
@ -47,7 +48,8 @@ export const preloadHandlebarsTemplates = async function () {
|
|||||||
"systems/bol/templates/dialogs/career-roll-part.hbs",
|
"systems/bol/templates/dialogs/career-roll-part.hbs",
|
||||||
"systems/bol/templates/dialogs/boons-roll-part.hbs",
|
"systems/bol/templates/dialogs/boons-roll-part.hbs",
|
||||||
"systems/bol/templates/dialogs/flaws-roll-part.hbs",
|
"systems/bol/templates/dialogs/flaws-roll-part.hbs",
|
||||||
"systems/bol/templates/dialogs/total-roll-part.hbs",
|
"systems/bol/templates/dialogs/total-roll-part.hbs",
|
||||||
|
"systems/bol/templates/dialogs/fightoptions-roll-part.hbs",
|
||||||
];
|
];
|
||||||
|
|
||||||
// Load the template parts
|
// Load the template parts
|
||||||
|
7
packs/fightoptions.db
Normal file
7
packs/fightoptions.db
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{"_id":"4VsEmcj4YpdAaaZY","name":"Attaque au Défaut d'armure","type":"feature","img":"icons/skills/melee/weapons-crossed-poleaxes-white.webp","data":{"category":null,"subtype":"fightoption","description":"<p>Vous visez une zone du corps non protégée ou un point faible de l’armure de votre adversaire.</p>\n<p>Appliquez la valeur de protection fixe de l’armure comme malus à votre jet d’attaque (-1 pour une armure légère, -2 pour une armure moyenne et -3 pour une armure lourde). Si votre attaque passe malgré ce malus, les dégâts de votre coup ignorent la protection de l’armure.</p>\n<p>Si le MJ l’accepte, cette option de combat pourra également permettre de trouver le défaut de l’armure naturelle d’une créature.</p>","properties":{"ismalusdice":false,"isbonusdice":false,"fightoptiontype":"armordefault","activated":false},"rank":0,"fightoptiontype":"armordefault"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"kQghu0tL1dft5xLu":3},"flags":{"core":{"sourceId":"Item.3nzfQvMvkK4ujRqI"}}}
|
||||||
|
{"name":"Posture Défensive","type":"feature","img":"icons/skills/melee/weapons-crossed-poleaxes-white.webp","data":{"category":null,"subtype":"fightoption","description":"<p>Vous choisissez d’adopter une attitude prudente, en restant toujours prêt à parer ou à esquiver l’attaque de votre adversaire. Combattre en posture défensive vous confère un bonus de +1 en défense, mais vous subissez un malus de -1 à votre jet d’attaque.</p>","properties":{"ismalusdice":false,"isbonusdice":false,"fightoptiontype":"defense","activated":false},"rank":0,"fightoptiontype":"defense"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"kQghu0tL1dft5xLu":3},"flags":{"core":{"sourceId":"Item.CS1fCtHTxp5v1krr"}},"_id":"FQPqaB86ZkRzsKwG"}
|
||||||
|
{"name":"Défense Totale","type":"feature","img":"icons/skills/melee/weapons-crossed-poleaxes-white.webp","data":{"category":null,"subtype":"fightoption","description":"<p>Vous consacrez votre round à esquiver, parer et vous protéger des coups. Vous n’ effectuez pas d’attaque durant le round, mais bénéficiez d’un bonus de +2 en défense, qui s’ajoute éventuellement à celui que pourrait vous apporter un bouclier ou une arme secondaire de parade.</p>","properties":{"ismalusdice":false,"isbonusdice":false,"fightoptiontype":"fulldefense","activated":false},"rank":0,"fightoptiontype":"fulldefense"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"kQghu0tL1dft5xLu":3},"flags":{"core":{"sourceId":"Item.t8v7isBpnFzAbmUI"}},"_id":"JRboSn5RuGILpH0B"}
|
||||||
|
{"name":"Combat à Deux Armes (Défensif)","type":"feature","img":"icons/skills/melee/weapons-crossed-poleaxes-white.webp","data":{"category":null,"subtype":"fightoption","description":"<p>Vous ne pouvez utiliser que des armes légères ou moyennes.</p>\n<p>Vous attaquez avec une arme et parez avec l’autre. Vous considérez l’arme de parade comme l’équivalent d’un petit bouclier (+1 en défense contre une attaque), mais vous subissez un malus de -1 sur votre jet d’attaque avec votre autre arme.</p>","properties":{"ismalusdice":false,"isbonusdice":false,"fightoptiontype":"twoweaponsdef","activated":false},"rank":0,"fightoptiontype":"twoweapons"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"kQghu0tL1dft5xLu":3},"flags":{"core":{"sourceId":"Item.lyMbLMPnFk0oXaSr"}},"_id":"JtU8EmKuda0M4Onv"}
|
||||||
|
{"_id":"a3Ev9xm8aM9kAmi3","name":"Attaque Intrépide","type":"feature","img":"icons/skills/melee/weapons-crossed-poleaxes-white.webp","data":{"category":null,"subtype":"fightoption","description":"<p>Vous attaquez avec la plus extrême témérité.</p>\n<p>Vous ne bénéficiez pas de l’éventuel bonus d’un bouclier ou d’une arme secondaire de parade et subissez un malus de -2 à la défense. En revanche, vous bénéficiez d’un bonus de +2 au jet d’attaque.</p>","properties":{"ismalusdice":false,"isbonusdice":false,"fightoptiontype":"intrepid","activated":false},"rank":0,"fightoptiontype":"intrepid"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"kQghu0tL1dft5xLu":3},"flags":{"core":{"sourceId":"Item.589BS9KBGnUazrFA"}}}
|
||||||
|
{"name":"Posture Offensive","type":"feature","img":"icons/skills/melee/weapons-crossed-poleaxes-white.webp","data":{"category":null,"subtype":"fightoption","description":"<p>Vous vous concentrez sur l’attaque, au détriment de votre défense. Cette option vous confère un bonus de +1 au jet d’attaque, mais vous subissez un malus de -1 en défense.</p>","properties":{"ismalusdice":false,"isbonusdice":false,"fightoptiontype":"attack","activated":false},"rank":0,"fightoptiontype":"attack"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"kQghu0tL1dft5xLu":3},"flags":{"core":{"sourceId":"Item.BF7F5WvL1pbWVHNq"}},"_id":"hgUHJP6JFxbeiRQL"}
|
||||||
|
{"name":"Combat à Deux Armes (Offensif)","type":"feature","img":"icons/skills/melee/weapons-crossed-poleaxes-white.webp","data":{"category":null,"subtype":"fightoption","description":"<p>Vous ne pouvez utiliser que des armes légères ou moyennes.</p>\n<p><span style=\"font-family: var(--font-primary); font-size: var(--font-size-14);\">Vous attaquez avec vos deux armes. </span><span style=\"font-family: var(--font-primary); font-size: var(--font-size-14);\">Vous n’effectuez qu’un seul jet d’attaque avec un </span>malus de -1, mais vous infligez des dégâts comme si vous maniez une arme moyenne (si vous utilisez deux armes légères) ou une arme lourde (si vous utilisez une arme moyenne et une arme légère, ou deux armes moyennes).</p>","properties":{"ismalusdice":false,"isbonusdice":false,"fightoptiontype":"twoweaponsatt","activated":false},"rank":0,"fightoptiontype":"twoweapons"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"kQghu0tL1dft5xLu":3},"flags":{"core":{"sourceId":"Item.lyMbLMPnFk0oXaSr"}},"_id":"wM4ZIVSSKApgzEmN"}
|
13
system.json
13
system.json
@ -7,8 +7,8 @@
|
|||||||
"url": "https://github.com/ZigmundKreud/bol",
|
"url": "https://github.com/ZigmundKreud/bol",
|
||||||
"license": "LICENSE.txt",
|
"license": "LICENSE.txt",
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"templateVersion": 21,
|
"templateVersion": 22,
|
||||||
"minimumCoreVersion": "0.8.6",
|
"minimumCoreVersion": "0.8.6",
|
||||||
"compatibleCoreVersion": "9",
|
"compatibleCoreVersion": "9",
|
||||||
"scripts": [],
|
"scripts": [],
|
||||||
@ -135,6 +135,15 @@
|
|||||||
"system": "bol",
|
"system": "bol",
|
||||||
"entity": "Item",
|
"entity": "Item",
|
||||||
"private": false
|
"private": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Options de Combat",
|
||||||
|
"type": "Item",
|
||||||
|
"name": "fightoptions",
|
||||||
|
"path": "packs/fightoptions.db",
|
||||||
|
"system": "bol",
|
||||||
|
"entity": "Item",
|
||||||
|
"private": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"system": [],
|
"system": [],
|
||||||
|
@ -26,13 +26,17 @@
|
|||||||
{{!-- Sheet Body --}}
|
{{!-- Sheet Body --}}
|
||||||
<section class="sheet-body">
|
<section class="sheet-body">
|
||||||
<div class="tab stats" data-group="primary" data-tab="stats">{{>
|
<div class="tab stats" data-group="primary" data-tab="stats">{{>
|
||||||
"systems/bol/templates/actor/parts/tabs/actor-stats.hbs"}}</div>
|
"systems/bol/templates/actor/parts/tabs/actor-stats.hbs"}}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="tab actions" data-group="primary" data-tab="actions">
|
<div class="tab actions" data-group="primary" data-tab="actions">
|
||||||
{{> "systems/bol/templates/actor/parts/tabs/actor-actions.hbs"}}
|
{{> "systems/bol/templates/actor/parts/tabs/actor-actions.hbs"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab combat" data-group="primary" data-tab="combat">
|
<div class="tab combat" data-group="primary" data-tab="combat">
|
||||||
{{> "systems/bol/templates/actor/parts/tabs/actor-combat.hbs"}}
|
{{> "systems/bol/templates/actor/parts/tabs/actor-combat.hbs"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab features" data-group="primary" data-tab="features">
|
<div class="tab features" data-group="primary" data-tab="features">
|
||||||
{{> "systems/bol/templates/actor/parts/tabs/actor-features.hbs"}}
|
{{> "systems/bol/templates/actor/parts/tabs/actor-features.hbs"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
{{#if blocking}}<div class="item-field">{{localize "BOL.ui.blocking"}}</div>{{/if}}
|
{{#if blocking}}<div class="item-field">{{localize "BOL.ui.blocking"}}</div>{{/if}}
|
||||||
{{#if weapon}}<div class="item-field">{{localize "BOL.ui.damages"}}</div>{{/if}}
|
{{#if weapon}}<div class="item-field">{{localize "BOL.ui.damages"}}</div>{{/if}}
|
||||||
{{#if ranged}}<div class="item-field">{{localize "BOL.ui.range"}}</div>{{else}}<div class="item-field"></div>{{/if}}
|
{{#if ranged}}<div class="item-field">{{localize "BOL.ui.range"}}</div>{{else}}<div class="item-field"></div>{{/if}}
|
||||||
|
{{#if options}}<div class="item-field">{{localize "BOL.ui.status"}}</div>{{else}}<div class="item-field"></div>{{/if}}
|
||||||
</li>
|
</li>
|
||||||
{{#each combatType.items as |item id|}}
|
{{#each combatType.items as |item id|}}
|
||||||
<li class="item flexrow" data-item-id="{{item._id}}">
|
<li class="item flexrow" data-item-id="{{item._id}}">
|
||||||
@ -15,6 +16,15 @@
|
|||||||
{{#if ../blocking}}<div class="item-field">{{item.data.properties.blocking.malus}}</div>{{/if}}
|
{{#if ../blocking}}<div class="item-field">{{item.data.properties.blocking.malus}}</div>{{/if}}
|
||||||
{{#if ../weapon}}<div class="item-field"><a class="rollable" data-roll-type="damage">{{item.data.properties.damage}}</a></div>{{/if}}
|
{{#if ../weapon}}<div class="item-field"><a class="rollable" data-roll-type="damage">{{item.data.properties.damage}}</a></div>{{/if}}
|
||||||
{{#if ../ranged}}<div class="item-field">{{item.data.properties.range}}</div>{{else}}<div class="item-field"></div>{{/if}}
|
{{#if ../ranged}}<div class="item-field">{{item.data.properties.range}}</div>{{else}}<div class="item-field"></div>{{/if}}
|
||||||
|
{{#if ../options}}<div class="item-field">
|
||||||
|
{{#if item.data.properties.activated}}
|
||||||
|
<a class="toggle-fight-option">{{localize "BOL.ui.toactivated"}}</a>
|
||||||
|
{{else}}
|
||||||
|
<a class="toggle-fight-option">{{localize "BOL.ui.todeactivated"}}</a>
|
||||||
|
{{/if}}
|
||||||
|
</div>{{else}}
|
||||||
|
<div class="item-field"></div>
|
||||||
|
{{/if}}
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ol>
|
</ol>
|
||||||
|
14
templates/chat/chat-activate-fight-option.hbs
Normal file
14
templates/chat/chat-activate-fight-option.hbs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<div>
|
||||||
|
<img class="chat-icon" src="{{img}}" alt="{{name}}"/>
|
||||||
|
<h2 class="good"><strong>{{name}}</strong></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
{{#if state}}
|
||||||
|
{{name}} active son option de combat {{foName}} pour ce round !
|
||||||
|
{{else}}
|
||||||
|
{{name}} désactive son option de combat {{foName}} pour ce round !
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
<div class="chat-message-header flexrow">
|
|
||||||
<img class="chat-icon" src="{{actorImg}}" alt="{{alias}}"/>
|
|
||||||
<h4 class=chat-actor-name>{{alias}}</h4>
|
|
||||||
</div>
|
|
||||||
<div class="flexrow">
|
|
||||||
<h3>
|
|
||||||
{{#if (eq mode "attribute")}}
|
|
||||||
{{localize attribute.label}}
|
|
||||||
{{else}}
|
|
||||||
{{#if (eq mode "career")}}
|
|
||||||
{{localize "Career"}} : {{career.name}}
|
|
||||||
{{else}}
|
|
||||||
{{#if (eq mode "weapon")}}
|
|
||||||
{{localize "Attack with"}} {{weapon.name}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="dice-roll">
|
|
||||||
<div class="dice-result">
|
|
||||||
<div class="dice-formula">{{formula}}</div>
|
|
||||||
<div class="dice-formula">{{modifier}}</div>
|
|
||||||
<div class="dice-tooltip" style="display: none;">
|
|
||||||
<section class="tooltip-part">
|
|
||||||
<div class="dice">
|
|
||||||
<header class="part-header flexrow">
|
|
||||||
<span class="part-formula">{{formula}}</span>
|
|
||||||
<span class="part-total">{{finalScore}}</span>
|
|
||||||
</header>
|
|
||||||
<ol class="dice-rolls">
|
|
||||||
<li class="roll die d6 discarded min">1</li>
|
|
||||||
<li class="roll die d6">2</li>
|
|
||||||
<li class="roll die d6">3</li>
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<h4 class="dice-total">{{finalScore}}</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,5 +1,7 @@
|
|||||||
<img class="chat-icon" src="{{img}}" alt="{{name}}"/>
|
<div>
|
||||||
<h3><strong>{{name}}</strong></h3>
|
<img class="chat-icon" src="{{img}}" alt="{{name}}"/>
|
||||||
|
<h2 class="bad"><strong>{{name}}</strong></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
|
|
||||||
|
@ -5,4 +5,5 @@
|
|||||||
<div id="{{applyId}}">
|
<div id="{{applyId}}">
|
||||||
<button class="chat-damage-apply" data-attack-id="{{id}}">Appliquer les dommages à la cible</button>
|
<button class="chat-damage-apply" data-attack-id="{{id}}">Appliquer les dommages à la cible</button>
|
||||||
</div>
|
</div>
|
||||||
|
<br>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -1,21 +1,30 @@
|
|||||||
<img class="chat-icon" src="{{actor.img}}" alt="{{actor.name}}"/>
|
<div>
|
||||||
{{#if isSuccess}}
|
{{#if isSuccess}}
|
||||||
{{#if isCritical}}
|
{{#if isCritical}}
|
||||||
<h2 class="success critical"><i class="fas fa-check-double"></i> {{localize "BOL.ui.critical"}}...</h2>
|
<h2 class="success critical"><i class="fas fa-check-double"></i> {{localize "BOL.ui.critical"}}...
|
||||||
{{else}}
|
{{else}}
|
||||||
<h2 class="success"><i class="fas fa-check"></i> {{localize "BOL.ui.success"}}...</h2>
|
<h2 class="success"><i class="fas fa-check"></i> {{localize "BOL.ui.success"}}...
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if isFailure}}
|
{{#if isFailure}}
|
||||||
{{#if isFumble}}
|
{{#if isFumble}}
|
||||||
<h2 class="failure fumble"><i class="fas fa-skull-crossbones"></i> {{localize "BOL.ui.fumble"}}...</h2>
|
<h2 class="failure fumble"><i class="fas fa-skull-crossbones"></i> {{localize "BOL.ui.fumble"}}...
|
||||||
{{else}}
|
{{else}}
|
||||||
<h2 class="failure"><i class="fas fa-times"></i> {{localize "BOL.ui.failure"}}...</h2>
|
<h2 class="failure"><i class="fas fa-times"></i> {{localize "BOL.ui.failure"}}...
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
<img class="chat-icon" src="{{actor.img}}" alt="{{actor.name}}"/>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3><strong>{{description}}</strong></h3>
|
<h3><strong>{{description}}</strong></h3>
|
||||||
|
|
||||||
|
{{#if fightOption}}
|
||||||
|
<div>
|
||||||
|
Option de combat : {{fightOption.name}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<div id="{{optionsId}}">
|
<div id="{{optionsId}}">
|
||||||
{{#if (and isSuccess weapon)}}
|
{{#if (and isSuccess weapon)}}
|
||||||
{{> "systems/bol/templates/chat/rolls/attack-damage-card.hbs"}}
|
{{> "systems/bol/templates/chat/rolls/attack-damage-card.hbs"}}
|
||||||
@ -33,4 +42,5 @@
|
|||||||
{{#if isRealCritical}}
|
{{#if isRealCritical}}
|
||||||
<button class="chat-button button transform-heroic-roll" data-roll-id=="{{rollId}}" data-actor-id="{{actor.id}}">Transformer en succes héroique (1 P. Heroisme)</button>
|
<button class="chat-button button transform-heroic-roll" data-roll-id=="{{rollId}}" data-actor-id="{{actor.id}}">Transformer en succes héroique (1 P. Heroisme)</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
<br>
|
||||||
</div>
|
</div>
|
@ -1,6 +1,10 @@
|
|||||||
<img class="chat-icon" src="{{defender.img}}" alt="{{defender.name}}"/>
|
<img class="chat-icon" src="{{defender.img}}" alt="{{defender.name}}"/>
|
||||||
Va encaisser {{damageTotal}} dégats !
|
Va encaisser {{damageTotal}} dégats !
|
||||||
|
|
||||||
|
{{#if damagesIgnoresArmor}}
|
||||||
|
<br>C'est une attaque au défaut de l'armure : vous devez encaisser SANS la protection de l'armure !
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<button class="damage-handling" data-defense-mode="damage-with-armor" data-attack-id="{{attackId}}">Encaisser avec la protection de l'armure</button>
|
<button class="damage-handling" data-defense-mode="damage-with-armor" data-attack-id="{{attackId}}">Encaisser avec la protection de l'armure</button>
|
||||||
<button class="damage-handling" data-defense-mode="damage-without-armor" data-attack-id="{{attackId}}">Encaisser sans la protection de l'armure</button>
|
<button class="damage-handling" data-defense-mode="damage-without-armor" data-attack-id="{{attackId}}">Encaisser sans la protection de l'armure</button>
|
||||||
|
|
||||||
|
10
templates/dialogs/fightoptions-roll-part.hbs
Normal file
10
templates/dialogs/fightoptions-roll-part.hbs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{{#if fightOption}}
|
||||||
|
<div class="flexrow" style="margin-bottom: 1px;">
|
||||||
|
<div class="flex1 center bg-darkred">
|
||||||
|
<label for="fg">{{localize 'BOL.ui.fightOption'}}</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex1 center cell">
|
||||||
|
{{fightOption.name}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
@ -45,10 +45,12 @@
|
|||||||
|
|
||||||
{{> "systems/bol/templates/dialogs/flaws-roll-part.hbs"}}
|
{{> "systems/bol/templates/dialogs/flaws-roll-part.hbs"}}
|
||||||
|
|
||||||
|
{{> "systems/bol/templates/dialogs/fightoptions-roll-part.hbs"}}
|
||||||
|
|
||||||
{{> "systems/bol/templates/dialogs/adv-roll-part.hbs"}}
|
{{> "systems/bol/templates/dialogs/adv-roll-part.hbs"}}
|
||||||
|
|
||||||
{{> "systems/bol/templates/dialogs/mod-roll-part.hbs"}}
|
{{> "systems/bol/templates/dialogs/mod-roll-part.hbs"}}
|
||||||
|
|
||||||
{{> "systems/bol/templates/dialogs/total-roll-part.hbs"}}
|
{{> "systems/bol/templates/dialogs/total-roll-part.hbs"}}
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
{{#if (equals data.subtype "career")}}
|
{{#if (equals data.subtype "career")}}
|
||||||
{{> "systems/bol/templates/item/parts/properties/feature/career-properties.hbs"}}
|
{{> "systems/bol/templates/item/parts/properties/feature/career-properties.hbs"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{!#if (equals data.subtype "origin")}}
|
{{#if (equals data.subtype "fightoption")}}
|
||||||
{{!> "systems/bol/templates/item/parts/properties/feature/origin-properties.hbs"}}
|
{{> "systems/bol/templates/item/parts/properties/feature/fightoption-properties.hbs"}}
|
||||||
{{!/if}}
|
{{/if}}
|
||||||
{{!#if (equals data.subtype "race")}}
|
{{!#if (equals data.subtype "race")}}
|
||||||
{{!> "systems/bol/templates/item/parts/properties/feature/race-properties.hbs"}}
|
{{!> "systems/bol/templates/item/parts/properties/feature/race-properties.hbs"}}
|
||||||
{{!/if}}
|
{{!/if}}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
<h3 class="form-header">{{localize "BOL.ui.fightOption"}}</h3>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="property-label">{{localize "BOL.ui.fightOptionType"}}</label>
|
||||||
|
<div class="form-fields">
|
||||||
|
<select name="data.properties.fightoptiontype" data-dtype="String">
|
||||||
|
{{#select data.properties.fightoptiontype}}
|
||||||
|
{{#each config.fightOptionTypes as |item id|}}
|
||||||
|
<option value="{{id}}">{{localize item}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="property flexrow">
|
||||||
|
<label class="property-label">{{localize "BOL.ui.activated"}}</label>
|
||||||
|
<input class="field-value" type="checkbox" name="data.properties.activated" {{checked data.properties.activated}}>
|
||||||
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user