ENH: Ability rolls and auto item tags

master
U~man 2020-07-12 16:16:48 +02:00
parent 10460834c2
commit 9b8dc1211d
12 changed files with 138 additions and 80 deletions

View File

@ -32,6 +32,9 @@
"OSE.roll.exploration": "{exploration} test",
"OSE.roll.details.exploration": "Roll 1d6 <= {expl} for success",
"OSE.roll.reaction": "Reaction roll",
"OSE.roll.type.result": "Result",
"OSE.roll.type.above": "Above",
"OSE.roll.type.below": "Below",
"OSE.details.name": "Name",
"OSE.details.class": "Class",
@ -169,6 +172,8 @@
"OSE.items.Quantity": "Qt.",
"OSE.items.Roll": "Roll",
"OSE.items.BlindRoll": "Blind",
"OSE.items.RollTarget": "Target",
"OSE.items.RollType": "Type",
"OSE.items.Damage": "Damage",
"OSE.items.Melee": "Melee",
"OSE.items.Missile": "Missile",

View File

@ -32,6 +32,9 @@
"OSE.roll.exploration": "Prueba de {exploration}",
"OSE.roll.details.exploration": "Tirar 1d6 <= {expl} para éxito",
"OSE.roll.reaction": "Tirada de Reacción",
"OSE.roll.type.result": "Resultado",
"OSE.roll.type.above": "Encima",
"OSE.roll.type.below": "Debajo",
"OSE.details.name": "Nombre",
"OSE.details.class": "Clase",
@ -167,6 +170,8 @@
"OSE.items.Quantity": "Qt.",
"OSE.items.Roll": "Tirada",
"OSE.items.BlindRoll": "Ciega",
"OSE.items.RollTarget": "Mira",
"OSE.items.RollType": "Tipo",
"OSE.items.Damage": "Daño",
"OSE.items.Melee": "CC",
"OSE.items.Missile": "Distancia",

View File

@ -32,6 +32,9 @@
"OSE.roll.exploration": "Test de {exploration}",
"OSE.roll.details.exploration": "Lancez 1d6 <= {expl} pour réussir",
"OSE.roll.reaction": "Jet de Réaction",
"OSE.roll.type.result": "Resultat",
"OSE.roll.type.above": "Au-Dessus",
"OSE.roll.type.below": "En-Dessous",
"OSE.details.name": "Nom",
"OSE.details.class": "Classe",
@ -109,9 +112,9 @@
"OSE.MeleeShort": "MEL",
"OSE.Melee": "Mêlée",
"OSE.MeleeBonus": "Bonus de Mêlée",
"OSE.MissileShort": "PRO",
"OSE.Missile": "Projectiles",
"OSE.MissileBonus": "Bonus de Projectile",
"OSE.MissileShort": "DIS",
"OSE.Missile": "Distance",
"OSE.MissileBonus": "Bonus à Distance",
"OSE.Initiative": "Initiative",
"OSE.InitiativeBonus": "Bonus d'Initiative",
"OSE.InitiativeShort": "INIT",
@ -167,9 +170,11 @@
"OSE.items.Quantity": "Qt.",
"OSE.items.Roll": "Jet",
"OSE.items.BlindRoll": "Aveugle",
"OSE.items.RollTarget": "Cible",
"OSE.items.RollType": "Type",
"OSE.items.Damage": "Dégâts",
"OSE.items.Melee": "Mêlée",
"OSE.items.Missile": "Projectile",
"OSE.items.Missile": "Distance",
"OSE.items.Slow": "Lent",
"OSE.items.ArmorAC": "CA",
"OSE.items.ArmorAAC": "CAA",

View File

@ -71,7 +71,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Above",
type: "above",
target: this.data.data.saves[save].value,
details: game.i18n.format("OSE.roll.details.save", { save: label }),
},
@ -99,7 +99,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Below",
type: "below",
target: this.data.data.details.morale,
},
},
@ -125,7 +125,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Below",
type: "below",
target: this.data.data.retainer.loyalty,
},
},
@ -151,7 +151,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Table",
type: "table",
table: {
2: game.i18n.format("OSE.reaction.Hostile", {
name: this.data.name,
@ -195,7 +195,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Check",
type: "check",
target: this.data.data.scores[score].value,
details: game.i18n.format("OSE.roll.details.attribute", {
score: label,
@ -226,7 +226,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Hit Dice",
type: "hit dice",
},
},
};
@ -257,7 +257,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Appearing",
type: "appearing",
},
},
};
@ -282,7 +282,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Below",
type: "below",
target: this.data.data.exploration[expl],
details: game.i18n.format("OSE.roll.details.exploration", {
expl: label,
@ -312,7 +312,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Damage",
type: "damage",
stat: attData.type,
scores: data.scores,
},
@ -389,7 +389,7 @@ export class OseActor extends Actor {
...this.data,
...{
rollData: {
type: "Attack",
type: "attack",
thac0: thac0,
weapon: {
parts: dmgParts,

View File

@ -7,6 +7,11 @@ export const OSE = {
con: "OSE.scores.con.long",
cha: "OSE.scores.cha.long",
},
roll_type: {
result: "OSE.roll.type.result",
above: "OSE.roll.type.above",
below: "OSE.roll.type.below"
},
saves_short: {
death: "OSE.saves.death.short",
wand: "OSE.saves.wand.short",
@ -60,5 +65,10 @@ export const OSE = {
"Ogre",
"Orcish",
"Pixie"
]
],
tags: {
melee: "OSE.items.Melee",
missile: "OSE.items.Missile",
slow: "OSE.items.Slow",
}
};

View File

@ -7,28 +7,28 @@ export class OseDice {
};
let die = roll.parts[0].total;
if (data.rollData.type == "Above") {
if (data.rollData.type == "above") {
// SAVING THROWS
if (roll.total >= result.target) {
result.isSuccess = true;
} else {
result.isFailure = true;
}
} else if (data.rollData.type == "Below") {
} else if (data.rollData.type == "below") {
// MORALE, EXPLORATION
if (roll.total <= result.target) {
result.isSuccess = true;
} else {
result.isFailure = true;
}
} else if (data.rollData.type == "Check") {
} else if (data.rollData.type == "check") {
// SCORE CHECKS (1s and 20s)
if (die == 1 || (roll.total <= result.target && die < 20)) {
result.isSuccess = true;
} else {
result.isFailure = true;
}
} else if (data.rollData.type == "Table") {
} else if (data.rollData.type == "table") {
// Reaction
let table = data.rollData.table;
let output = "";
@ -251,7 +251,7 @@ export class OseDice {
speaker: speaker
};
if (skipDialog) {
return data.rollData.type === "Attack"
return data.rollData.type === "attack"
? OseDice.sendAttackRoll(rollData)
: OseDice.sendRoll(rollData);
}
@ -264,7 +264,7 @@ export class OseDice {
rolled = true;
rollData.form = html[0].children[0];
roll =
data.rollData.type === "Attack"
data.rollData.type === "attack"
? OseDice.sendAttackRoll(rollData)
: OseDice.sendRoll(rollData);
},

View File

@ -102,19 +102,23 @@ export class OseItem extends Item {
}
async rollFormula(options = {}) {
if (!this.data.data.roll) {
const data = this.data.data;
if (!data.roll) {
throw new Error("This Item does not have a formula to roll!");
}
const label = `${this.name}`;
const rollParts = [this.data.data.roll];
const rollParts = [data.roll];
const data = {
let type = data.rollType;
const newData = {
...this.data,
...{
rollData: {
type: "Formula",
blindroll: this.data.data.blindroll,
type: type,
target: data.rollTarget,
blindroll: data.blindroll,
},
},
};
@ -123,7 +127,7 @@ export class OseItem extends Item {
return OseDice.Roll({
event: options.event,
parts: rollParts,
data: data,
data: newData,
skipDialog: true,
speaker: ChatMessage.getSpeaker({ actor: this }),
flavor: game.i18n.format("OSE.roll.formula", { label: label }),
@ -144,8 +148,8 @@ export class OseItem extends Item {
getTags() {
let formatTag = (tag) => {
if (!tag) return "";
return `<li class='tag'>${tag}</li>`
}
return `<li class='tag'>${tag}</li>`;
};
const data = this.data.data;
switch (this.data.type) {
@ -156,11 +160,63 @@ export class OseItem extends Item {
case "item":
return "";
case "spell":
return `${formatTag(data.class)}${formatTag(data.range)}${formatTag(data.duration)}${formatTag(CONFIG.OSE.saves_long[data.save])}${formatTag(data.roll)}`;
return `${formatTag(data.class)}${formatTag(data.range)}${formatTag(
data.duration
)}${formatTag(CONFIG.OSE.saves_long[data.save])}${formatTag(
data.roll
)}`;
case "ability":
return `${formatTag(data.requirements)}${formatTag(data.roll)}`;
}
return "TEST";
return "";
}
pushTag(values) {
const data = this.data.data;
let update = [];
if (data.tags) {
update = duplicate(data.tags);
}
let newData = {};
var regExp = /\(([^)]+)\)/;
if (update) {
values.forEach((val) => {
// Catch infos in brackets
var matches = regExp.exec(val);
let title = "";
if (matches) {
title = matches[1];
val = val.substring(0, matches.index);
}
// Auto fill checkboxes
switch (val) {
case CONFIG.OSE.tags.melee:
newData.melee = true;
break;
case CONFIG.OSE.tags.slow:
newData.slow = true;
break;
case CONFIG.OSE.tags.missile:
newData.missile = true;
break;
}
update.push({ title: title, value: val });
});
} else {
update = values;
}
newData.tags = update;
console.log(newData);
return this.update({ data: newData });
}
popTag(value) {
const data = this.data.data;
let update = data.tags.filter((el) => el.value != value);
let newData = {
tags: update,
};
return this.update({ data: newData });
}
/**

View File

@ -51,41 +51,6 @@ export class OseItemSheet extends ItemSheet {
/* -------------------------------------------- */
_pushTag(values) {
const data = this.object.data.data;
let update = [];
if (data.tags) {
update = duplicate(data.tags);
}
var regExp = /\(([^)]+)\)/;
if (update) {
values.forEach(val => {
// Catch infos in brackets
var matches = regExp.exec(val);
let title = "";
if (matches) {
title = matches[1];
val = val.substring(0, matches.index);
}
update.push({title: title, value: val});
})
} else {
update = values;
}
let newData = {
tags: update
};
return this.object.update({ data: newData });
}
_popTag(value) {
const data = this.object.data.data;
let update = data.tags.filter((el) => el.value != value);
let newData = {
tags: update
};
return this.object.update({ data: newData });
}
/**
* Activate event listeners using the prepared sheet HTML
* @param html {HTML} The prepared HTML object ready to be rendered into the DOM
@ -95,12 +60,12 @@ export class OseItemSheet extends ItemSheet {
if (event.which == 13) {
let value = $(ev.currentTarget).val();
let values = value.split(',');
this._pushTag(values);
this.object.pushTag(values);
}
});
html.find('.tag-delete').click((ev) => {
let value = ev.currentTarget.parentElement.dataset.tag;
this._popTag(value);
this.object.popTag(value);
});
super.activateListeners(html);
}

View File

@ -62,7 +62,7 @@ Hooks.once("init", async function () {
*/
Hooks.once("setup", function () {
// Localize CONFIG objects once up-front
const toLocalize = ["saves_short", "saves_long", "scores", "armor", "colors"];
const toLocalize = ["saves_short", "saves_long", "scores", "armor", "colors", "roll_type", "tags"];
for (let o of toLocalize) {
CONFIG.OSE[o] = Object.entries(CONFIG.OSE[o]).reduce((obj, e) => {
obj[e[0]] = game.i18n.localize(e[1]);

View File

@ -2,22 +2,14 @@
"name": "ose",
"title": "Old-School Essentials",
"description": "Play B/X OSR modules with Old-School Essentials on Foundry VTT",
"version": 0.8,
"version": 0.9,
"minimumCoreVersion": "0.6.2",
"compatibleCoreVersion": "0.6.5",
"templateVersion": 2,
"author": "U~man",
"esmodules": ["ose.js"],
"styles": ["ose.css"],
"packs": [
{
"name": "OSEMacros",
"label": "Old School Essentials Macros",
"system": "ose",
"path": "./packs/macros.db",
"entity": "Macro"
}
],
"packs": [],
"languages": [
{
"lang": "en",
@ -39,5 +31,5 @@
"gridUnits": "ft",
"url": "https://gitlab.com/mesfoliesludiques/foundryvtt-ose",
"manifest": "https://gitlab.com/mesfoliesludiques/foundryvtt-ose/raw/master/src/system.json",
"download": "https://gitlab.com/mesfoliesludiques/foundryvtt-ose/-/raw/master/package/ose-v0.8.zip"
"download": "https://gitlab.com/mesfoliesludiques/foundryvtt-ose/-/raw/master/package/ose-v0.9.zip"
}

View File

@ -210,6 +210,8 @@
"ability": {
"requirements": "",
"roll": "",
"rollType": "result",
"rollTarget": 0,
"blindroll": false,
"description": ""
}

View File

@ -22,6 +22,24 @@
<input type="text" name="data.roll" value="{{data.roll}}" data-dtype="String" />
</div>
</div>
<div class="form-group block-input">
<label>{{localize 'OSE.items.RollType'}}</label>
<div class="form-fields">
<select name="data.rollType">
{{#select data.rollType}}
{{#each config.roll_type as |t a|}}
<option value="{{a}}">{{t}}</option>
{{/each}}
{{/select}}
</select>
</div>
</div>
<div class="form-group">
<label>{{localize 'OSE.items.RollTarget'}}</label>
<div class="form-fields">
<input type="text" name="data.rollTarget" value="{{data.rollTarget}}" data-dtype="Number" />
</div>
</div>
<div class="form-group">
<label>{{localize 'OSE.items.BlindRoll'}}</label>
<div class="form-fields">