diff --git a/css/deltagreen.css b/css/deltagreen.css
index 2f581bb..7f67973 100644
--- a/css/deltagreen.css
+++ b/css/deltagreen.css
@@ -843,10 +843,14 @@ input.item-sheet-short-input{
text-align: left;
}
-.add-typed-skill-button{
+.skill-buttons{
margin: 10px;
}
+.apply-skill-improvements{
+ float: right;
+}
+
.yellow-king{
color: #a0912f;
}
diff --git a/lang/en.json b/lang/en.json
index df166af..01310ba 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -46,6 +46,12 @@
"DG.Skills.AddTypedOrCustomSkill": "Add Typed or Custom Skill",
"DG.Skills.AddSkill": "Add Skill",
+ "DG.Skills.Apply": "Apply",
+ "DG.Skills.ApplySkillImprovements": "Apply Skill Improvements",
+ "DG.Skills.ApplySkillImprovementsChatFlavor": "Improved the following skills by",
+ "DG.Skills.ApplySkillImprovementsDialogLabel": "Improve skills by the following formula:",
+ "DG.Skills.ApplySkillImprovementsDialogEffectsFollowing": "Effects the following skills:",
+ "DG.Skills.ApplySkillImprovementsWarning": "No failed skills to improve.",
"DG.Skills.EditTypedOrCustomSkill": "Edit Typed or Custom Skill",
"DG.Skills.EditSkill": "Edit Skill",
"DG.Skills.SkillGroup": "Skill Group",
diff --git a/module/actor/actor-sheet.js b/module/actor/actor-sheet.js
index 4f195a5..b826037 100644
--- a/module/actor/actor-sheet.js
+++ b/module/actor/actor-sheet.js
@@ -246,6 +246,55 @@ export class DeltaGreenActorSheet extends ActorSheet {
});
+ html.find('.apply-skill-improvements').click(event => {
+
+ event.preventDefault();
+
+ const failures = Object.entries(this.actor.data.data.skills).filter((skill) => skill[1].failure);
+ if (failures.length === 0) {
+ ui.notifications.warn('No Skills to Increase')
+ return;
+ }
+
+ let htmlContent = "";
+ let failedSkillNames = "";
+ failures.forEach(([skill], value) => {
+ if (value === 0) {
+ failedSkillNames += (game.i18n.localize("DG.Skills." + skill));
+ } else {
+ failedSkillNames += `, ${(game.i18n.localize("DG.Skills." + skill))}`;
+ }
+ })
+
+ htmlContent += `
`;
+ htmlContent += ` `;
+ htmlContent += ` `;
+ htmlContent += ` `;
+ htmlContent += ` `;
+ htmlContent += ` `;
+ htmlContent += ` `;
+ htmlContent += ` `;
+ htmlContent += `
`;
+ htmlContent += ` ${game.i18n.localize("DG.Skills.ApplySkillImprovementsDialogEffectsFollowing")} ${failedSkillNames} `;
+ htmlContent += ``;
+
+ new Dialog({
+ content: htmlContent,
+ title: game.i18n.translations.DG?.Skills?.ApplySkillImprovements ?? "Apply Skill Improvements",
+ default: "add",
+ buttons: {
+ apply:{
+ label: game.i18n.translations.DG?.Skills?.Apply ?? "Apply",
+ callback: btn =>{
+ const baseRollForumla = btn.find("[name='roll-formula']").val();
+ this._applySkillImprovements(baseRollForumla, failures);
+ },
+ }
+ }
+ }).render(true);
+
+ });
+
// Browse Weapon Compendiums
html.find('.weapon-browse').click(ev => {
const dialog = new Dialog({
@@ -389,7 +438,7 @@ export class DeltaGreenActorSheet extends ActorSheet {
let newTypeSkillLabel = btn.find("[name='new-type-skill-label']").val();
let newTypeSkillGroup = btn.find("[name='new-type-skill-group']").val();
this._addNewTypedSkill(newTypeSkillLabel, newTypeSkillGroup);
- }
+ },
}
}
}).render(true);
@@ -621,6 +670,63 @@ export class DeltaGreenActorSheet extends ActorSheet {
}
}
+ _applySkillImprovements(baseRollFormula, failures) {
+ const actorData = this.actor.data.data;
+ const resultList = [];
+ let rollFormula;
+
+ switch (baseRollFormula) {
+ case "1":
+ rollFormula = 1;
+ break;
+ case "1d3":
+ rollFormula = `${failures.length}d3`;
+ break;
+ case "1d4":
+ case "1d4-1":
+ rollFormula = `${failures.length}d4`;
+ break;
+ default:
+ }
+
+ let roll;
+ if (rollFormula !== 1) {
+ roll = new Roll(rollFormula, actorData);
+ roll.evaluate({async: true});
+ roll.terms[0].results.forEach((result) => resultList.push(baseRollFormula === "1d4-1" ? result.result - 1 : result.result));
+ }
+
+ let updatedSkills = "";
+
+ failures.forEach(([skill], value) => {
+ const updatedData = duplicate(actorData);
+ updatedData.skills[skill].proficiency += resultList[value] ?? 1;
+ updatedData.skills[skill].failure = false;
+ this.actor.update({"data": updatedData});
+
+ // So we can record the skills and how much they were increased by in chat.
+ if (updatedSkills === "") {
+ updatedSkills += `${game.i18n.localize("DG.Skills." + skill)}: +${resultList[value] ?? 1}%`;
+ } else {
+ updatedSkills += `, ${game.i18n.localize("DG.Skills." + skill)}: +${resultList[value] ?? 1}%`;
+ }
+ })
+
+ const chatData = {
+ speaker: ChatMessage.getSpeaker({actor: this.actor, token: this.token, alias: this.actor.data.name}),
+ content: updatedSkills,
+ flavor: `${game.i18n.localize("DG.Skills.ApplySkillImprovementsChatFlavor")} +${baseRollFormula}%:`,
+ type: baseRollFormula === "1" ? 0 : 5, // 0 = CHAT_MESSAGE_TYPES.OTHER, 5 = CHAT_MESSAGE_TYPES.ROLL
+ roll: baseRollFormula === "1" ? null : roll, // If adding flat +1, there is no roll.
+ rollMode: game.settings.get("core", "rollMode")
+ };
+
+ // play the dice rolling sound, like a regular in-chat roll
+ if (roll) AudioHelper.play({src: "sounds/dice.wav", volume: 0.8, autoplay: true, loop: false}, true);
+
+ ChatMessage.create(chatData, {});
+ }
+
_onDragStart(event) {
const li = event.currentTarget;
if ( event.target.classList.contains("entity-link") ) return;
diff --git a/module/settings.js b/module/settings.js
index fc569f1..f69ef5e 100644
--- a/module/settings.js
+++ b/module/settings.js
@@ -33,15 +33,35 @@ export const registerSystemSettings = function() {
onChange: value => { // A callback function which triggers when the setting is changed
//console.log(value)
}
- });
+ });
- game.settings.register('deltagreen', 'keepSanityPrivate', {
- name: "Keep Sanity Private",
- hint: "Hide sanity from players on both character sheet and rolls.",
- scope: "world",
- config: true,
- type: Boolean,
- default: false
- });
+ game.settings.register('deltagreen', 'keepSanityPrivate', {
+ name: "Keep Sanity Private",
+ hint: "Hide sanity from players on both character sheet and rolls.",
+ scope: "world",
+ config: true,
+ type: Boolean,
+ default: false
+ });
+
+ game.settings.register('deltagreen', 'skillImprovementFormula', {
+ name: "Default Skill Improvement Roll",
+ hint: " Default 1d4. There have been multiple errata on this, choose which fits best for the pace of your game.",
+ scope: "world", // This specifies a world-stored setting
+ config: true, // This specifies that the setting appears in the configuration view
+ type: String,
+ choices: { // If choices are defined, the resulting setting will be a select menu
+ "1": "Flat +1",
+ "1d3": "+1D3%",
+ "1d4": "+1D4%",
+ "1d4-1": "+1D4-1%"
+ },
+ default: "1d4", // The default value for the setting, per the most recent errata.
+ onChange: value => { // A callback function which triggers when the setting is changed
+ //console.log(value)
+ }
+ });
+
+
}
\ No newline at end of file
diff --git a/templates/actor/actor-sheet.html b/templates/actor/actor-sheet.html
index d4694ab..898a447 100644
--- a/templates/actor/actor-sheet.html
+++ b/templates/actor/actor-sheet.html
@@ -134,8 +134,9 @@